ACodec.cpp revision 97358c3e1adaf4a744cad78891a16d12e3e9c88e
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
3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4345778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4397a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
468054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
469054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
492ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
496afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
499308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
500308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
506ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
510308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
537eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
542eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
552054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
553054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5815ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5843c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5853c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6113c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
630258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6728ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6731e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
68074006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
68174006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68374006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68574006804065941841883c4b46ee785070164023fJamie Gennis
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
69029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
69174006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69674006804065941841883c4b46ee785070164023fJamie Gennis
6973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70974006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
712054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
799f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8008ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
805c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
806c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
840d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
847d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
848d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8792ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8802ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9402944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9412944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
948729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
949729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
952c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
953c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
96294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
964ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
965ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
968ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
969ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
970774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
971774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
97297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
97397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1050308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1051308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1052308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1054308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1101a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1102a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1103a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1104a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1117fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1118fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1119fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1120fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1121fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1122fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11630167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11640167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11650167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11660167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11670167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11680167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1171308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
118342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
118442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
118542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
118642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
118742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
118842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
119042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
119142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
119242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
119342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
119442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
119542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1203ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1204ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1206aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1207aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1208aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1210ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12114471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12124471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1214729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1218729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1219729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1220729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1221729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1222729de186450f78c099637e1fce743fe531862c52Andreas Huber
1223729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1238516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1239516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1242516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1244516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1247516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1248516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1249516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1253516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1256ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1257ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1258ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1259ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1260ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1261ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1262ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1263ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1264ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
126597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
126697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
126797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
126897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
126997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
127097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
127197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
127297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
127397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1275729de186450f78c099637e1fce743fe531862c52Andreas Huber
12764471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12774471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12784471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12794471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12839806555d3930be43e11106281dee354820ac1c88Andreas Huber
12848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12858b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12868b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12878b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12889806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12899806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12909806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12919806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12929806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12939806555d3930be43e11106281dee354820ac1c88Andreas Huber
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1368aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1369aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1370ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1371ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1372ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1373ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1434aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1460ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1462ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1463ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1464ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
147197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
147297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
147397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
147497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
147597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
147697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
147797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
147897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
147997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
148097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
148197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
148297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
148397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
148497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
148597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
148697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
148797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1554729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1555729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1557729de186450f78c099637e1fce743fe531862c52Andreas Huber
1558729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1559729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1560729de186450f78c099637e1fce743fe531862c52Andreas Huber
1561729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1562729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1563729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1564729de186450f78c099637e1fce743fe531862c52Andreas Huber
1565729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber
15882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1616729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1617729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1619729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1620729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1621729de186450f78c099637e1fce743fe531862c52Andreas Huber
1622729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1623729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1624729de186450f78c099637e1fce743fe531862c52Andreas Huber
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1627729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1640729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber
1642729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1643729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1644729de186450f78c099637e1fce743fe531862c52Andreas Huber
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber
1656c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1657c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
174894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
174994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
202296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
202396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
202496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
202596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
202696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
202796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
202896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
202996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
203096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
203896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
203996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
210396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
211996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
212096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
217996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
219596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
219696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22497c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22507c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22517c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
232396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
233696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2415d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2416d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2417d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2418d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2419d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2420d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2421d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2422d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2423d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2424d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2425d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2426d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2427d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2428d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24297e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24437e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2462c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2463c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2464c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2465c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2506577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
250731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
250831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
250931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
251031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
251131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
251231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
251331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
251431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
251531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
251631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
251731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
251831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
251931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
252031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
252131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
252231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
252331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
252431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
253531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
253631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
253731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2571577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2572577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2573577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2574577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2575577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2576577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
257831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
257931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
258031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
258331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
258431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
258531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
259814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
260114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
260214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
260314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
260414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
260514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
260614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
261614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
261714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
261814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
262114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
262214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
262314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26288b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26319806555d3930be43e11106281dee354820ac1c88Andreas Huber
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26549806555d3930be43e11106281dee354820ac1c88Andreas Huber
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
269197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
269297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
269397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
269497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
269597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
269697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
269797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
269897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
269997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
270097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
270197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
270297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
270397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
270497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
270597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
270697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
270797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
270897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
271331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
271431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
271531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
271631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
271731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
271831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
271931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
272031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
272131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
272231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
272331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
272431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2726cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2727cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2728cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2730cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2731cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2732cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
276687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
276787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
276887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
276987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
277087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
277187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2861bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2862bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2880eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2881eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2882eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2883496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2884496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2885496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2886496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2887496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2888496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2889496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2890496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2891496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2892496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2893496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2894496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2895496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2896496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2897496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2898496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2899496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2900496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2901eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2902eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2903eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2904eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2905eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2906eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2907eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2908eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2909eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2910eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2911eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2912eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2913eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2914eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2915eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2916eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2917eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2918eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2919eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2920eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2921f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2957ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2958ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2959ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2960ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2961ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2962ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2963ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29870af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29880af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29890af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29900af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29910af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29920af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29930af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29940af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29960af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29970af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3063349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3074d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
307996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
308096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
308196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31212d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31372d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3140a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31422d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3143a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
31473831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
31483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3150a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        mode = KEEP_BUFFERS;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3168dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3169dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3170dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3171dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3194d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3195d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3203078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3205078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3209078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3215078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3217078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3218349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3226054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3227054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3228054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3229054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3231054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3234054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3235054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3236054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3237054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3239054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3261dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3263dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3264dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3265dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3267dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3268dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3272349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3285dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3334349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3336d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3337d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3342d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3343d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3344d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3345d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3346d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3347d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3348d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3349d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3350d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3351d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3357054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3371349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
337931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3380577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3381577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3382577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3384577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3387308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3388308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3389308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3390308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3391308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3392308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3393308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3394308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3395308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3396496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
339721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3398496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3399496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3400496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
340221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34122d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3428dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3458577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3459577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3460577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3461577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3462577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3463577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3464577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
34676aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
34686aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34741e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3475cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3476cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3478cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3479cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3512c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3514c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3515c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3518c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3536f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3542ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3543ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3544ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3545ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3546ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3547ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3548ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3549ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3550ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3551ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3552ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3553308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3554ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3588c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3598c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3626ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3627ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3628ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3629ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3630ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3631ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3632ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3633ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3634ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3635e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3640d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3642e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3643e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3644e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3645afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3646e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3647e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3648e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3649afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3663e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36651065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
36671065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
36681065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3671e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3672e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3674078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3675078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3676078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36771065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3678078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36851065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3687c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3694c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3695cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3697c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3699ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3703ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3704ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3705ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3706ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37070167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3708ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3709ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3710afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3735f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3736f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3737f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3738f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3739f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3742a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3791c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3800c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3832c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3833c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3834c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3840386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38421173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38431173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38441173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38451173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38461ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38471ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38481ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38491ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3859c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
38677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
38687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3874a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3875a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3876a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3877a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3878a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3879a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3880a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3881a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3882a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3883a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3884a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3885a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3886a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3887a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3888a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3889a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3890a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
39007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
39017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
39027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
39037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
39047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3905c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
39095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
39223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3924cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3925cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
392629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3927cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3928cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3929cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
39305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
393191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
393291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3933cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
39676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39746463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
40093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4021d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4022d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4023d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4024d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4025d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4026d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4027d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4028d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4029d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4030d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4031d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4032d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4033d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4034d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4035d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
40366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4068f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4069349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4070349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4073f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4082054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4108349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4117c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4124349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
41253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4126349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4127349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4128349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4129349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4130349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4138349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4139349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4156c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4157c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4158c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4159c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4160c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41757a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4176d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4177d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4178d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4179d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4180d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4181d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4182d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4183349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4184349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4203496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4204496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4205496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4206496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4207496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4208496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4209496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4210496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4211496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4212496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4224a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4225a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4226a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4227a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4228a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4229a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4246a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4247530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4248a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4249a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4250a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4251a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4260a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4261a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4262a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4263a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4264a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4265a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4266a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4267e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4268e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4269e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4270e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4271b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4272b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4273e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4274e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4275e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4276e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4277b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4278b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4279b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4280b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4281b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4282b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4283b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4284b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4285b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4286b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4287b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4288b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4289b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4290b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4291b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4292b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4293e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4294e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4295a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4296a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4297a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42986507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
42996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
43006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
43016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
43026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
43036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
43046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
43056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
43066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
43076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
43086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
431631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4317054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
432631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
432731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
43293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4353f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4371349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4375349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4376349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
43913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4413cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4414cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4415cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
441629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4417cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4418cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4419cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4421d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4422755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4423755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4424755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4425755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4426755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4427755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4428755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4429755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4430cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
443731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4441349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4442349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4443349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4444349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4460f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
44615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
44625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
44943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
449531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
449731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
45095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4516349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4518349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4519349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4520349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4521349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
45285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45360167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
45370167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
45983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4621f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
46263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
46587a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4659d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4660d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4669e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4670e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4671e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4672e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4673e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4685349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4686349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4687349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4688349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4689349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4690349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4691349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4692349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4693349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4697349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4698349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4699349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4700349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4701349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
47257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
47267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
47277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
47287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4736dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4737dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4738f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4739f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4740f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4741f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4747