ACodec.cpp revision f3bd1972e039c6ded5154db715e5a32f1813a239
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
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
172f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
174c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
176f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
185c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
186c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
187c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
189c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
1967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
197c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
204c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
208f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
213f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
221f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
224f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
245349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
246349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
255349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
256349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
338afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
339afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
341c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
3429806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3439806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3449806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3459806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3469806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
348c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
361dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
366f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
369f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
373f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
380a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
381a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
382a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
383a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
384a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3855778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3915778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
3987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
3997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4055778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
409f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4107a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
420c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
421c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
424496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
425496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
426496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
427496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
428f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
461afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
462afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
463afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
464afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
466ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
467ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
468ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
469ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
470ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
471ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(ptr, def.nBufferSize);
475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
477ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
482ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
483ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
4871065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
4881065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
499eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
500eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
501eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
503eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
505eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
53329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5393c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5403c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5413c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5425ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5433c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5443c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5453c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5463c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
558bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
559bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
560bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5723c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
579258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
580258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
581258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
582258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
583258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
584258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
58529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
586258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
587258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
588258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
589258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
590258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
591258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
592258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
593258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
594258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
595258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
596258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
597258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
598258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
599258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
60029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
601258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
602258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
603258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
604258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
605258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
62074006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6218ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6221e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
62429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
62974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
63074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
63121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen        info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */);
63274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
63374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
63474006804065941841883c4b46ee785070164023fJamie Gennis
635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
63929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
64074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
64574006804065941841883c4b46ee785070164023fJamie Gennis
6463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
65874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
6801e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
6908ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
6911e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
6921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
69329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
694c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
695c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        if (info->mStatus !=
732349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                BufferInfo::OWNED_BY_COMPONENT) {
733349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We shouldn't have sent out any buffers to the client at this
734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // point.
735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            CHECK_NE((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
764f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
7942944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
7952944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
7962944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
7972944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
804729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
805729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
806c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
807c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
808c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
809c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        { MEDIA_MIMETYPE_VIDEO_VPX,
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            "video_decoder.vpx", "video_encoder.vpx" },
818ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
819ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
822ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
823ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8585ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
8842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
8852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
8862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
890d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
891d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
892d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
893d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
894d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
895d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
896d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
897d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
898d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                  mComponentName.c_str(), err);
899d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
900d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            return err;
901d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        }
902d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
903d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
9043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    int32_t prependSPSPPS;
9053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
9063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
9073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
9083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
9093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
9103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
9113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
9123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
9133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
9153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
9163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
9173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
9183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
9203a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
9213a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9223a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9233a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
9243a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
9253a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
9263a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9273a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
9283a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9293a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
9303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!strncasecmp(mime, "video/", 6)) {
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
949aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
950ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
951ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
952ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
953aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
954aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
955aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
956ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
957ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
9584471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
9594471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
961729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
963729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
965729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
966729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
967729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
968729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
969729de186450f78c099637e1fce743fe531862c52Andreas Huber
970729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
9772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
9782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
9802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
9812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
9822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
9832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
9842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
985516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
986516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
9872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
9882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
989516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
990516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
991516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
9922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
9932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
994516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
995516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
996516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
9972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
9982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
9992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1000516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1001516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
10022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1003ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1004ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1005ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1006ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1007ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1008ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1009ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1010ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1011ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1013729de186450f78c099637e1fce743fe531862c52Andreas Huber
10144471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
10154471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
10164471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
10174471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
10188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
10198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
10208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10219806555d3930be43e11106281dee354820ac1c88Andreas Huber
10228b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
10238b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
10248b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
10269806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
10279806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
10289806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
10299806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
10309806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10319806555d3930be43e11106281dee354820ac1c88Andreas Huber
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1106aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1107aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1108ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1109ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1110ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1111ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
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        profile.nChannels = numChannels;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1172aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1198ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1200ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1202ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1254729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1255729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1257729de186450f78c099637e1fce743fe531862c52Andreas Huber
1258729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1259729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1260729de186450f78c099637e1fce743fe531862c52Andreas Huber
1261729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1263729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1264729de186450f78c099637e1fce743fe531862c52Andreas Huber
1265729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1270729de186450f78c099637e1fce743fe531862c52Andreas Huber
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1274729de186450f78c099637e1fce743fe531862c52Andreas Huber
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1279729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1280729de186450f78c099637e1fce743fe531862c52Andreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber
12882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
12892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
12902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
12922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
12932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
12942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
12952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
12962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
12972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
12982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
12992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
13002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
13032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
13042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
13052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
13062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
13092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
13112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
13122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
13132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
13142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
13152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1316729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1317729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1318729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1319729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1320729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1321729de186450f78c099637e1fce743fe531862c52Andreas Huber
1322729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1323729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1324729de186450f78c099637e1fce743fe531862c52Andreas Huber
1325729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1326729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1327729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1328729de186450f78c099637e1fce743fe531862c52Andreas Huber
1329729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1330729de186450f78c099637e1fce743fe531862c52Andreas Huber
1331729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1332729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1333729de186450f78c099637e1fce743fe531862c52Andreas Huber
1334729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1335729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1336729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1337729de186450f78c099637e1fce743fe531862c52Andreas Huber
1338729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1339729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1340729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1341729de186450f78c099637e1fce743fe531862c52Andreas Huber
1342729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1343729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1344729de186450f78c099637e1fce743fe531862c52Andreas Huber
1345729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1346729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1347729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1348729de186450f78c099637e1fce743fe531862c52Andreas Huber
1349729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1350729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1351729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1352729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1353729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1354729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1355729de186450f78c099637e1fce743fe531862c52Andreas Huber
1356c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1357c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1358729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1359729de186450f78c099637e1fce743fe531862c52Andreas Huber
1360729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1361729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1362729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1363729de186450f78c099637e1fce743fe531862c52Andreas Huber
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber           || format.eColorFormat == OMX_COLOR_FormatCbYCrY
14381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber           || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
143918faac2af4e3b27deec0a707757883e5e569c591Haynes Mathew George           || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
14400f6675d5fdf15d4b8765545fb6a351138acccdf6SeungBeom Kim           || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
14410f6675d5fdf15d4b8765545fb6a351138acccdf6SeungBeom Kim           || format.eColorFormat == OMX_SEC_COLOR_FormatNV12Tiled);
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingAVC;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG4;
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingH263;
1456386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingMPEG2;
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VPX, mime)) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingVPX;
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        *codingType = OMX_VIDEO_CodingUnused;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
16590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
16600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
16610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
16620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
16640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
16660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
16670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
16680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
16690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
16700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
16710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
16720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
16730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
16750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
16760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
16770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
16780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
16790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
16800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
16810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
16830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
16840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
16850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
16860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
16870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
16880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
16900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
16910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
16920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
16930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
16940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
170696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
170796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
170896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
170996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
171096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
171196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
171296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
171396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
171496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
172296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
172396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
178796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
180396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
180496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
186396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
187996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
188096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
18910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
18920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
18930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
18940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
18950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
18960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
18970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
18980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
19337c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
19347c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
19357c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
197796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
200696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
200796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
202096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2052f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2090f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2099d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2100d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2101d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2102d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2103d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2104d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2105d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2106d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2107d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2108d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2109d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2110d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2111d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2112d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2113f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
21203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
215031e2508c75018145a8238925ff1a08cbde4e799aAndreas Hubervoid ACodec::sendFormatChange() {
215131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
215231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
215331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
215431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
215531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
215631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
215731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
215831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
215931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
216031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
216131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
216231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
216331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
216431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
216531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
216631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
216731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
216831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
216931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
217031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
217131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("stride", videoDef->nStride);
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("slice-height", videoDef->nSliceHeight);
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("color-format", videoDef->eColorFormat);
217531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
217631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_CONFIG_RECTTYPE rect;
217731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&rect);
217831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            rect.nPortIndex = kPortIndexOutput;
217931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
218031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mOMX->getConfig(
218131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexConfigCommonOutputCrop,
218231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &rect, sizeof(rect)) != OK) {
218331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nLeft = 0;
218431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nTop = 0;
218531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nWidth = videoDef->nFrameWidth;
218631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                rect.nHeight = videoDef->nFrameHeight;
218731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
218831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
218931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nLeft, 0);
219031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nTop, 0);
219131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nWidth, 0u);
219231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_GE(rect.nHeight, 0u);
219331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
219431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
219531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
219631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setRect(
219731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    "crop",
219831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft,
219931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop,
220031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nLeft + rect.nWidth - 1,
220131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                    rect.nTop + rect.nHeight - 1);
220231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
220331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (mNativeWindow != NULL) {
220431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                android_native_rect_t crop;
220531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.left = rect.nLeft;
220631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                crop.top = rect.nTop;
220789c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.right = rect.nLeft + rect.nWidth;
220889c120e7adbe09c6283591789594c5e591aa5032Andreas Huber                crop.bottom = rect.nTop + rect.nHeight;
220931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
221031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                CHECK_EQ(0, native_window_set_crop(
221131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                            mNativeWindow.get(), &crop));
221231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
221331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
221431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
221531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
221631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
221731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
221831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
221931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
222031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
222131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PARAM_PCMMODETYPE params;
222231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            InitOMXParams(&params);
222331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            params.nPortIndex = kPortIndexOutput;
222431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
222531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(mOMX->getParameter(
222631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        mNode, OMX_IndexParamAudioPcm,
222731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                        &params, sizeof(params)),
222831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                     (status_t)OK);
222931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
223031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK(params.nChannels == 1 || params.bInterleaved);
223131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ(params.nBitPerSample, 16u);
223231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
223331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
223431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
223531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
223631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("channel-count", params.nChannels);
223731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("sample-rate", params.nSamplingRate);
22388b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mEncoderDelay + mEncoderPadding) {
22398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                size_t frameSize = params.nChannels * sizeof(int16_t);
22408b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                if (mSkipCutBuffer != NULL) {
22418b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    size_t prevbufsize = mSkipCutBuffer->size();
22428b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    if (prevbufsize != 0) {
22438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                        ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
22448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
22458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
22468b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
22478b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                                                   mEncoderPadding * frameSize);
22488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
22499806555d3930be43e11106281dee354820ac1c88Andreas Huber
22509806555d3930be43e11106281dee354820ac1c88Andreas Huber            if (mChannelMaskPresent) {
22519806555d3930be43e11106281dee354820ac1c88Andreas Huber                notify->setInt32("channel-mask", mChannelMask);
22529806555d3930be43e11106281dee354820ac1c88Andreas Huber            }
22539806555d3930be43e11106281dee354820ac1c88Andreas Huber
225431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
225531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
225631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
225731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
225831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
225931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
226031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
226131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
226231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
226331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
226431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
226531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
22665778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2267cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2268cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2269cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2271cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2272cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2273cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2274bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2275bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2276bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2277bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2278bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2279bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2280bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2281bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2282bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2283bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2284bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2285bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2286bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2287bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2288bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2289bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2290bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2291bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2292bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2293bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2294bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2295bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2296bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2297bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2298bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2299bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2300bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2301bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2302bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2303bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2304bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2305bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2306bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2307bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2308bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2309bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2310bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2311bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2312bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2313bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2314bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2315bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2316bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2317bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2318bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2319bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2320bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2321bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2322bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2323bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2324bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2325bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2326bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2327bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2328bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2329bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2330bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2331bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2332bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2333bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2334bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2335bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
23361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
23371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2338bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2339bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2340bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2341bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2342bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2343bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2344bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2345bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2346bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2347bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2348bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2349bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2350bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2351bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2352bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2353bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2354bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2355bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2356bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2357bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2358bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2359bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
23651e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2366bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2367bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2368bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2369bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2370bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2371bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2372bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2373bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2374bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2375bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2376bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2377bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
23801e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2383bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2384bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2385bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2386bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2387bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2388bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2389bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2390bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2391bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2392bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2393bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2394bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2395bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2396bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2397bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2398bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2399bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2400bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2401bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2402bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2403bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2404bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2405bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2406bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2407bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2408bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2409bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2410bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2413eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2414eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2415eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2416496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2417496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2418496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2419496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2420496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2421496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2422496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2423496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2424496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2425496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2426496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2427496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2428496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2429496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2430496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2431496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2432496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2433496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2434eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2435eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2436eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2437eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2438eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2439eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2440eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2441eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2442eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2443eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2444eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2445eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2446eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2447eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2448eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2449eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2450eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2451eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2452eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2453eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
24837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
24847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
24857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
24867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
24877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
24887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
24897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
25130af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
25140af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
25150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
25160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
25170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
25180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
25190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
25200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
25210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
25220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
25230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
25733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2581cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2586f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
25873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2588349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2596d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2598d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2599d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2600d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2601d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2603d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2604d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
260596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
260696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
260796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2608d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2609d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2610d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2611d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2612d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2613d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2635f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
26472d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26632d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
26665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26672d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
26713831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
26723831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
26732d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
26825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2695dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2696dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2697dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2698dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
27055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
27175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
27185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
27195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2721d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
2722d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
2723d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
2724d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
2725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2730078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
27313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2732078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
27335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2736078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
2737d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2738d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
2739d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2740d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
27413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2742078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2743d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2744078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2745349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2746d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2747d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
2748d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
2749d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
2750d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
2751d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2752d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
27655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
27665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
27685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2774dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
27753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2776dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2777dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2778dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
27793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2780dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2781dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2784349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2785349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
2798dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
28455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
28465778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
2847349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2849d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2850d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2851d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
2852d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
2853d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
2854d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
2855d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2856d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
2857d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
2858d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
2859d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2860d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
2861d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
2862d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2863d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2864d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
2883349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
28865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
28895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
28905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
289131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
28925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
28935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->sendFormatChange();
28945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            info->mData->setRange(rangeOffset, rangeLength);
2897496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
289821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
2899496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
2900496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
2901496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
29025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
290321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
29068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
29078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
29085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
29115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
29125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
29132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
29145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> reply =
29175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                new AMessage(kWhatOutputBufferDrained, mCodec->id());
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
29245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
29285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
29295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
2932dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && msg->findInt32("render", &render) && render != 0) {
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
29701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
2971cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
2972cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
2974cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
2975cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3006c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
30073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3008c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3009349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3010c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3011c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3013c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3014c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3032f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3036c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3037c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3038c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
30535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
30545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
30555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3064c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3065c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3071c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3081c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
31005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
31015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3116e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3117e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3118e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3119afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3120e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3121e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3122e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3123afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
31365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3137e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
31401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
31411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
31421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
31431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
31441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3145e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3146e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3148078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3149078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3150078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
31511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3152078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
31551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
31561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
31571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
31581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
31591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
31601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3161c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
31625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
31635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
31645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
31655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3168c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3169cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3170c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3171c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3178ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3183afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
31975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3199c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3200c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3202c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3203c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3204c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3208f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3209f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3210f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3211f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3212f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3227c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNativeWindow.clear();
3228c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mNode = NULL;
3229c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mOMX.clear();
3230afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        mCodec->mQuirks = 0;
3231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags = 0;
3232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mComponentName.clear();
3233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3238c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3239c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3247c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3248c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3249c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3250c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3252c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
32537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
32547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
32557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
32567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
32577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
32587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
32597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3260c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3261c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3262c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3263c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3264c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3265c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3266c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3267c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3268c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3271c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3272c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3273c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3283c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3284c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3285c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3291c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3308c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3309c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3310c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3316386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
33181173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
33191173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
33201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
33211173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
33221ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
33231ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
33241ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
33251ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3334c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3335c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
33397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
33407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
33417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
33427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
33437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
33447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
33457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
33467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
33477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
33487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
33497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
33507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
33517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
33527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
33537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
33547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
33557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
33567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
33577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
33587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
33597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
33607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
33617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
33627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
33637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
33685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3376f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
33813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3384cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
338529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3386cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3387cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3388cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
33895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
339091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
339191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3392cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
34146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
34156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
34166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
34176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
34186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
34196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
34206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
34216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
34226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
34236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
34246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
34256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
34266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
34276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
34286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
34296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
34306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
34316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
34326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
34336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3463f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
34683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3480d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3481d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3482d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3483d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3484d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3485d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3486d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3487d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3488d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3489d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3490d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3491d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3492d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3493d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3494d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
34956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
34966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
34976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
34986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
34996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
35006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3532f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3553349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3554349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3563349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
35643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3565349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3577349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3578349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
35823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3598c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3600349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3601349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
36147a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3615d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3616d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3617d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3618d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3619d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3620d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3621d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3622349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3641496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
3642496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
3643496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
3644496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
3645496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
3646496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
3647496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3648496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
3649496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
3650496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
3651496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3652a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
3653a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
3654a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
3655a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
3656a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3657a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
3658a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3659a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
3660a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
3661a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
3662a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
3663a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
3664a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3665a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
3666a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
3667a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
3668a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
36697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
36707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
36716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
36727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
36737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
36747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3684a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
3685a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
3686a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
3687a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
3688a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
3689a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
3690a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
3691a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3692a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
3693a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
3694a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
3695a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
3696a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
3697a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3698a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
3699a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
3700a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
3701a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3702a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
3703a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
3704a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
3705a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3706a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
3707a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
3708a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
37096507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
37106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
37116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
37126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
37136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
37146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
37156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
37166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
37176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
37186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
37196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
372731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3733349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
373631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
373731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
37393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3763f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3781349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3783349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
37843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
3785349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
3786349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
38013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
3811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3823cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
3824cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
3825cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
382629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
3827cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
3828cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
3829cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
3831d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3832755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
3833755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
3834755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
3835755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
3836755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
3837755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
3838755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
3839755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
3840cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
384731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
38483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3851349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
3852349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
3853349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
3854349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
39043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
390531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
390731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3925349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
3926349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
3927349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
3928349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
3929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
3930349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
3931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
39360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
39385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
3947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
3948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
3949bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
3950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
3951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
3952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3974f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
40073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
40353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
40677a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4068d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4069d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4078e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4079e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4080e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4081e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4082e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4097349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4098349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4099349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4100349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4101349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
41033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4105349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4106349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4109349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4110349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4141dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4142dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4143f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4144f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4145f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4146f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4152