ACodec.cpp revision ba933df89521d63f75ca66af12ce9d7ae9496b9e
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
41f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
42f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
44f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
242349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
243349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
253349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
254349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
336afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
337afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
339c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3409806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3419806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3439806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3449806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
346c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
359dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
364f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
371f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
3947a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
409496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
410496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
442ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
443ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
446afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
447afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
448afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
452ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
453ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
454ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
463ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
464ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
465ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
466ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
467ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
483eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
484eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
485eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
487eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
489eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
51729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5243c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5253c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5265ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5273c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5293c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5303c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
531bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
532bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5563c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
564258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
565258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
566258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
567258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
568258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
56929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
570258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
571258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
572258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
573258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
574258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
575258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
576258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
577258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
578258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
579258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
580258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
581258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
582258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
583258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
585258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
586258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
587258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
588258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
589258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
59429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
60474006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
60829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
61374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
61474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
61574006804065941841883c4b46ee785070164023fJamie Gennis        info.mData = new ABuffer(0);
61674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
61774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
61874006804065941841883c4b46ee785070164023fJamie Gennis
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
62329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
62474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
62974006804065941841883c4b46ee785070164023fJamie Gennis
6303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
64274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
6641e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6748ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
6751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
6761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
67729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
678c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
679c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
719349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
720349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
748f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7782944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7792944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7802944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7812944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
788729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
789729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
790c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
791c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
792c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
793c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
802ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
803ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
806ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
807ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8425ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
8692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
8702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
874d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
875d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
876d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
877d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
878d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
879d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
880d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
881d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
882d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                  mComponentName.c_str(), err);
883d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
884d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
885d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
886d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
887d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
8883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    int32_t prependSPSPPS;
8893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
8903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
8913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
8923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
8933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
8943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
8953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
8963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
8973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
8983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
8993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
9003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
9013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
9023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
9043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
9053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
9083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
9093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
9103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
9123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
9143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
933aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
934ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
935ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
936ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
937aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
938aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
939aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
940ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
941ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
9424471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
9434471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
945729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
947729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
949729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
950729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
951729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
952729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
953729de186450f78c099637e1fce743fe531862c52Andreas Huber
954729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
9612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
9622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
9632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
9662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
9672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
9682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
9692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
9702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
9712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
9722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
9732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
9742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
9752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
9762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
9772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
9782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
9802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
981ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
982ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
983ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
984ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
985ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
986ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
987ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
988ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
989ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
991729de186450f78c099637e1fce743fe531862c52Andreas Huber
9924471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
9934471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
9944471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
9954471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
9968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
9978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
9988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
9999806555d3930be43e11106281dee354820ac1c88Andreas Huber
10008b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
10018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
10028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
10049806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
10059806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
10069806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
10079806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
10089806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10099806555d3930be43e11106281dee354820ac1c88Andreas Huber
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1084aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1085aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1086ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1087ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1088ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1089ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1150aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1176ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1178ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1232729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1233729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1235729de186450f78c099637e1fce743fe531862c52Andreas Huber
1236729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1237729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1238729de186450f78c099637e1fce743fe531862c52Andreas Huber
1239729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1240729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1241729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1242729de186450f78c099637e1fce743fe531862c52Andreas Huber
1243729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1248729de186450f78c099637e1fce743fe531862c52Andreas Huber
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1252729de186450f78c099637e1fce743fe531862c52Andreas Huber
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1257729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1258729de186450f78c099637e1fce743fe531862c52Andreas Huber
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1263729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1264729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1265729de186450f78c099637e1fce743fe531862c52Andreas Huber
12662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
12682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
12702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
12712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
12722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
12732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
12752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
12782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
12812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
12842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
12852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
12862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
12872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
12892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
12902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
12912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
12922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
12932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1294729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1295729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1296729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1297729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1298729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1299729de186450f78c099637e1fce743fe531862c52Andreas Huber
1300729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1301729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1302729de186450f78c099637e1fce743fe531862c52Andreas Huber
1303729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1304729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1305729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1306729de186450f78c099637e1fce743fe531862c52Andreas Huber
1307729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1308729de186450f78c099637e1fce743fe531862c52Andreas Huber
1309729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1310729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1311729de186450f78c099637e1fce743fe531862c52Andreas Huber
1312729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1313729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1314729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1315729de186450f78c099637e1fce743fe531862c52Andreas Huber
1316729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1317729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1318729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1319729de186450f78c099637e1fce743fe531862c52Andreas Huber
1320729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1321729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1322729de186450f78c099637e1fce743fe531862c52Andreas Huber
1323729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1324729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1325729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1326729de186450f78c099637e1fce743fe531862c52Andreas Huber
1327729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1328729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1329729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1330729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1331729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1332729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1333729de186450f78c099637e1fce743fe531862c52Andreas Huber
1334c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1335c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1336729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1337729de186450f78c099637e1fce743fe531862c52Andreas Huber
1338729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1339729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1340729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1341729de186450f78c099637e1fce743fe531862c52Andreas Huber
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
14161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
141718faac2af4e3b27deec0a707757883e5e569c591Haynes Mathew George           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
141818faac2af4e3b27deec0a707757883e5e569c591Haynes Mathew George           || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka);
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingAVC;
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG4;
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingH263;
1433386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG2;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingVPX;
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingUnused;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
164696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
164796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
164896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
164996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
165096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
165196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
165296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
165396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
165496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
166296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
166396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
172796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
174396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
174496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
180396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
181996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
182096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
18627c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
18637c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
18647c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
190696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
193596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
193696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
194996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1981f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
1982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
1984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
1989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
1996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
1997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
1998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
1999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2019f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2028d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2029d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2030d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2031d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2032d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2033d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2034d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2035d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2036d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2037d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2038d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2039d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2040d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2041d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2042f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
20493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207931e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
208031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
208131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
208231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
208431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
208531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
208631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
208731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
208831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
208931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
209031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
209231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
209431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
209531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
209631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
209731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
209831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
209931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
210031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("stride", videoDef->nStride);
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("slice-height", videoDef->nSliceHeight);
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("color-format", videoDef->eColorFormat);
210431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
210531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
210631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
210731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
210831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
210931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
211031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
211131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
211231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
211331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
211431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
211531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
211631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
211731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
211831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
211931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
212031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
212131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
212231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
212331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
212431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
212531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
212631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
212731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
212831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
212931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
213031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
213131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
213231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
213331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
213431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
213531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
213689c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
213789c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
213831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
213931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
214031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
214131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
214231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
214331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
214431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
214531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
214631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
214731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
214831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
214931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
215031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
215131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
215231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
215331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
215431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
215531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
215631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
215731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
215831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
215931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
216031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
216131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
216231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
216331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
216431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
216531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
216631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
21678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mEncoderDelay + mEncoderPadding) {
21688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                size_t frameSize = params.nChannels * sizeof(int16_t);
21698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                if (mSkipCutBuffer != NULL) {
21708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    size_t prevbufsize = mSkipCutBuffer->size();
21718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    if (prevbufsize != 0) {
21728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
21738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
21748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
21758b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
21768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                                                   mEncoderPadding * frameSize);
21778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
21789806555d3930be43e11106281dee354820ac1c88Andreas Huber
21799806555d3930be43e11106281dee354820ac1c88Andreas Huber            if (mChannelMaskPresent) {
21809806555d3930be43e11106281dee354820ac1c88Andreas Huber                notify->setInt32("channel-mask", mChannelMask);
21819806555d3930be43e11106281dee354820ac1c88Andreas Huber            }
21829806555d3930be43e11106281dee354820ac1c88Andreas Huber
218331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
218431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
218531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
218631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
218731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
218831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
218931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
219031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
219131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
219231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
219331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
219431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2196cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2197cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2198cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2200cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2201cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2202cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2203bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2204bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2205bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2206bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2207bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2208bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2209bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2210bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2211bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2212bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2213bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2214bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2215bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2216bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2217bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2218bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2219bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2220bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2221bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2222bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2223bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2224bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2225bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2226bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2227bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2228bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2229bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2230bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2231bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2232bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2233bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2234bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2235bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2236bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2237bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2238bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2239bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2240bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2241bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2242bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2243bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2244bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2245bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2246bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2247bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2248bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2249bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2250bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2251bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2252bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2253bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2254bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2255bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2256bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2257bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2258bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2259bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2260bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2261bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2262bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2263bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2264bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
22651e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
22661e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2267bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2268bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2269bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2270bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2271bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2272bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2273bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2274bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2275bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2290bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
22941e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2303bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
23091e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2311bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2312bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2313bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2314bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2318bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2319bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2320bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2321bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2322bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2323bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2324bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2336bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2337bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2338bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2339bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2342eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2343eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2344eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2345496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2346496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2347496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2349496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2353496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2354496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2355496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2356496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2357496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2359496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2360496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2361496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2362496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2363eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2364eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2365eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2366eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2367eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2368eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2369eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2370eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2371eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2372eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2373eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2374eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2375eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2376eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2377eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2378eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2379eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2380eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2381eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2382eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2383f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2388f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
24350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
24360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
24370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
24380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
24390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
24400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
24410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
24420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
24430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
24440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
24943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
250029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2502cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
25083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2509349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2510349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2517d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2518d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2519d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2520d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2521d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2522d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2523d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2524d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2525d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
252696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
252796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
252896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2530d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2531d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2532d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2533d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2534d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
25682d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25842d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
25923831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
25933831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
25942d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2616dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2617dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2618dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2619dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2642d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
2643d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
2644d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
2645d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2651078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
26523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2653078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2657078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
2658d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2659d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
2660d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2661d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
26623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2663078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2664d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2665078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2666349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2667d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2668d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
2669d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
2670d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
2671d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
2672d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
26905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
26925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2695dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
26963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2697dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2698dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2699dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
27003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2701dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2702dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2705349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2706349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2719dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
2762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
2763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
2764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
2765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
2768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2770d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2771d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2772d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
2773d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
2774d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
2775d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
2776d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2777d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
2778d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
2779d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
2780d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2781d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
2782d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
2783d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2785d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
28025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
28035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
2804349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
28055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
28065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
28075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
28105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
28115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
281231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
28135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
28145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->sendFormatChange();
28155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mCodec->mNativeWindow == NULL) {
28185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mData->setRange(rangeOffset, rangeLength);
2819496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2820496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
2821496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
2822496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
2823496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
2824496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#endif
28255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28278b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
28288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
28298b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
28305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
28335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
28345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
28352d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
28365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> reply =
28395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                new AMessage(kWhatOutputBufferDrained, mCodec->id());
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
28505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
28515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
2854dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
28921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
2893cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
2894cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
28955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
2896cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
2897cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
29293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
2930c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
2931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2932c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
2933c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2935c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2936c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2954f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2958c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
2959c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
2960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
2961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
29755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
29765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
29775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
29785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
29795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
29805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2983c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
2984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
2985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
2986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
2987c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
2993c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3003c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3016c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3017c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3021c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3024c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3031e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
30325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
30375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3038e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3039e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3040e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3041afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3042e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3043e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3044e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3045afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3059e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
30631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
30641065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
30661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3067e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3068e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3071078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3072078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
30731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3074078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30761065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
30771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
30781065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
30791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
30801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
30811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
30821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3083c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3090c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3091cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3092c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3093c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3099ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3100ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3105afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3110349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3111349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3112dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mCodec->mInputEOSResult = OK;
3113dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3126c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3130c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3131c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3132c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3133c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3134c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3135c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3136c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3137c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3138c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3139c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3140c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3141c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3142c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3143c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3144c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3145c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3146c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3147c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3148c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3149c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNativeWindow.clear();
3150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNode = NULL;
3151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mOMX.clear();
3152afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodec->mQuirks = 0;
3153ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags = 0;
3154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mComponentName.clear();
3155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3156c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3159c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3160c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3161c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3162c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3163c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3164c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3165c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3166c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3167c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3168c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3169c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3170c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3171c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3172c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3173c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3174c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3175c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3176c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3181c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3182c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3183c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3184c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3204c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
32125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3223c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3224c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3225c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
32265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3231386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
32331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
32341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
32351173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
32361173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
32371ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
32381ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
32391ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
32401ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
32485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
32525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3253c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
32703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3272cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3273cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
327429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3275cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3276cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3277cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
327991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
328091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3281cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
33363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3374349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3375349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
34103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3411349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3412349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3413349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3414349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3415349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3423349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
34283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3446349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3447349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34607a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3461d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3462d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3463d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3464d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3465d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3466d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3467d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3488496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
3489496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
3490496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
3491496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
3492496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
3493496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
3494496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3495496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
3496496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
3497496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
3498496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3520349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
352331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
352431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
35263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3545f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3550f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3570349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
35713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3572349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
3573349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
35883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3610cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
3611cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
3612cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
361329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
3614cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
3615cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
3616cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
3618d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3619755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
3620755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
3621755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
3622755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
3623755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
3624755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
3625755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
3626755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
3627cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
363431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
36353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3638349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
3639349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
3640349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
3641349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
36913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
369231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
369431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3712349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3713349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
3714349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3715349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
3716349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3717349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3718349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
37230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
3734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
3735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
3736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
3737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
3738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
3739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3761f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
37943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3817f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
38223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
38547a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
3855d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
3856d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
3865e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
3866e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
3867e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
3868e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
3869e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3882349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3883349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
3884349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
3885349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
3886349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
3887349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
3888349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
3889349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
38903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
3891349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
3892349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3893349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
3894349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3895349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3896349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3897349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3928dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
3929dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
3935