ACodec.cpp revision 625b93f1971039a547b239f87a2dc8a8d5716589
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
4574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
512308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
520308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
522308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
526ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
548eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
549eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
564054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
62629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
644054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
645054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
649258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
65129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
66129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6848ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6851e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
69274006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
69374006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
69574006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
69674006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
69774006804065941841883c4b46ee785070164023fJamie Gennis
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70374006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
70874006804065941841883c4b46ee785070164023fJamie Gennis
7093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
72174006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8128ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8151e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
81629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
817c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
818c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
853d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
855d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
859d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
863d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
864d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
884349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8892ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8912ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9502944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9512944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9522944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9532944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
960729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
961729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
962c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
963c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
964c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
965c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
97294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
97394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
97494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
97594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
976ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
977ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
980ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
981ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
982774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
983774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
98497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
98597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1059308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1062308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1063308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1064308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1066308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1111a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1112a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1113a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1117308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1173054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11750167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11760167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11770167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11780167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11790167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1183308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
119542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
119642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
119742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
119842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
119942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
120042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
120142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
120242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
120342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
120442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
120542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
120642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
120742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1218aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1220aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12244471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1226729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1228729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1230729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1231729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1232729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1233729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1234729de186450f78c099637e1fce743fe531862c52Andreas Huber
1235729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1251516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1255516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1256516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1259516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1260516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1261516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1265516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1266516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1268ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1269ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1270ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1271ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1272ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1273ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1274ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1275ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1276ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
127797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
127897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
127997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
128097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
128197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
128297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
128397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
128497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
128597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1287729de186450f78c099637e1fce743fe531862c52Andreas Huber
12884471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12894471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12904471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12914471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12928b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12959806555d3930be43e11106281dee354820ac1c88Andreas Huber
12968b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13009806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13019806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13029806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13039806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13049806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13059806555d3930be43e11106281dee354820ac1c88Andreas Huber
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1380aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1381aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1382ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1383ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1384ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1385ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1446aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1472ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1473ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1474ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1475ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1476ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
148397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
148497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
148597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
148697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
148797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1628729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1640729de186450f78c099637e1fce743fe531862c52Andreas Huber
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1642729de186450f78c099637e1fce743fe531862c52Andreas Huber
1643729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1644729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1666729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1667729de186450f78c099637e1fce743fe531862c52Andreas Huber
1668c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1669c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
176094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
176194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
197789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
197889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
197989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
198089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
198189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
203996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
204096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
204196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
204296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
204396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
204496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
204596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
204696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
204796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
205696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
213696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
213796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
219696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
221396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22667c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22677c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22687c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
231489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
231589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
231689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
231789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
231889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
231989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
232089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
232189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
232289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
232389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
235196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
236496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2443d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2444d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2445d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2446d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2447d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2448d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2449d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2450d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2451d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2452d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2453d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2454d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2455d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2456d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24577e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24717e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2490c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2491c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2492c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2493c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2534577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
253531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
253631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
253731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
253831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
253931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
254031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
254131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
254331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
254431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
254531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
254731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
254931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
255031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
255131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
255231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
256331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
256431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
256531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2599577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2600577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2601577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2602577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2603577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2604577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
260631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
260731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
260831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
260931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
261031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
261131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
261231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
261331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
261497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
262614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
262914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
263014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
263114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
263214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
263314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
263414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
264414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
264514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
264614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
264914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
265014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
265114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26599806555d3930be43e11106281dee354820ac1c88Andreas Huber
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26829806555d3930be43e11106281dee354820ac1c88Andreas Huber
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
272097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
272197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
272297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
272397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
272497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
272597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
272697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
272797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
272897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
272997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
273097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
273197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
273297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
273397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
273497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
273597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
273697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
274131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
274231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
274331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
274431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
274531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
274631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
274731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
274831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
274931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
275031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
275131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
275231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27535778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2754cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2755cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2756cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2758cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2759cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2760cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
279487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
279587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
279687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
279787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
279887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
279987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28311e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2861bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2862bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2890bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2891bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2896bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2897bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2898bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2908eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2909eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2910eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2911496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2912496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2913496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2914496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2915496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2916496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2917496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2918496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2920496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2921496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2922496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2923496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2924496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2925496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2926496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2927496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2928496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2929eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2930eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2931eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2932eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2933eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2934eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2935eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2936eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2937eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2938eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2939eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2940eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2941eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2942eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2943eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2944eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2946eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2947eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2948eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2954f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2985ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2986ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2987ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2988ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2989ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2990ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2991ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
30160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
30170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
30180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
30190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
30200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
30210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
30220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
30230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
30240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
30250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3083cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3090349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
310796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
310896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
310996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3168a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31702d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3171a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31747fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31757fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31767fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
31777fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
31787fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
31797fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
31807fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31817fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31823831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31832d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3201dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3202dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3203dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3204dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
32235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
32245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
32255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3236078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3238078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3242078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3248078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3250078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3251349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3252d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3253d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3255d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3256d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3262054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3263054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3267054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3268054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3269054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3270054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3271054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3272054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3294dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3296dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3297dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3298dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3300dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3301dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3304349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3305349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3318dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3322625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3323625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3324625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3325625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3367349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3370d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3371d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3372d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3373d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
341231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3413577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3414577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3415577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
34164bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3417577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3420308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3421308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3422308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3423308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3424308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3425308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3427308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3428308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3429496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
343021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3431496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3432496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3433496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
343521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34388b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34452d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3461dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3492577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3493577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3494577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3495577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3496577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3497577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
35006aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
35016aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
35071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3508cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3509cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3511cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3512cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3543c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3545c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3546349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3547c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3548c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3550c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3551c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3569f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3573c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3574c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3575ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3576ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3577ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3578ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3579ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3580ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3581ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3582ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3583ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3584ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3585ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3586308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3587ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3621c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3631c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3659ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3660ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3661ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3662ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3663ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3664ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3665ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3666ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3667ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3668e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3673d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3675e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3676e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3677e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3678afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3679e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3680e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3681e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3682afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3696e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
37001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
37011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37021065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
37031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3704e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3705e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3707078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3708078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3709078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
37101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3711078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
37141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
37151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
37161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
37181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
37191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3720c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3727c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3728cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3730c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3732ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3736ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3737ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3738ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3739ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37400167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3741ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3742ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3743afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3768f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3769f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3770f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3771f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3772f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3775a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3791c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3800c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
38107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
38127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
38137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
38147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
38157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3839c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3843c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3865c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3866c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3867c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3873386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38751173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38761173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38771173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38781173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38791ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38801ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38811ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38821ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3891c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3892c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
39007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
39037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
39047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
39067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3907a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3908a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3909a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3910a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3911a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3912a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3913a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3914a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3915a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3916a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3917a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3918a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3919a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3920a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3921a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3923a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
39247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
39257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
39267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
39277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
39287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
39297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
39307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
39317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
39327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
39337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
39347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
39357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
39367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
39377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3938c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
39395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
39405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
39425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3950f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
39553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3957cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3958cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
395929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3960cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3961cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3962cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
39635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
396491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
396591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3966cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
40006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
40026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
40036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
40056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4037f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
40423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4053d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4054d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4055d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4056d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4057d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4058d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4059d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4060d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4061d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4062d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4063d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4064d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4065d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4066d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4067d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4068d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
40696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4101f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4102349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4106f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
41224dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
41234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
41244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4143349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4144349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4152054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4153c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4160349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
41613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4164349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4165349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4166349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4174349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4175349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4190c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4191c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4197349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42117a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4212d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4213d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4214d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4215d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4216d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4217d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4218d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4219349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4220349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4238496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4239496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4240496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4241496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4242496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4243496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4244496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4245496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4246496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4247496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4248496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4249a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4250a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4251a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4260a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4261a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4262a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4263a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4264a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4265a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
42734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
42754dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
42764dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
42774dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
42784dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
42794dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
42804dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
42814dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
42824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
42834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
42844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
42854dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4294a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4295a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4296530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4297a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4298a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4299a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4300a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4301a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4302a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4303a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4304a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4305a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4306a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4307a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4308a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4309a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4310a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4311a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4312a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4313a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4314a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4315a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4316e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4317e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4318e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4319e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4320b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4321b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4322e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4323e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4324e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4325e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4326b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4327b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4328b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4329b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4330b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4331b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4332b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4333b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4334b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4335b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4336b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4337b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4338b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4339b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4340b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4341b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4342e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4343e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4344a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4345a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4346a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43476507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
43486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
43496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
43506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
43516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
43526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
43536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
43546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
43556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
43566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
43576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4366054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
437531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
437631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
43783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4420349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4422349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
44233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4424349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4425349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
44403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4463cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4464cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
446529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4466cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4467cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4468cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4470d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4471755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4472755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4473755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4474755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4475755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4476755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4477755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4478755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4479cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
448631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4491349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4492349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4493349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4509f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
45105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
45115778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
45433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
454431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
454631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
45585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4564349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4565349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4566349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4567349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4568349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4569349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4570349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45850167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
45860167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
46473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4670f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
46753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47077a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4708d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4709d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4718e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4719e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4720e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4721e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4722e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4734349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4735349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4736349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4737349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4738349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4739349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4740349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4741349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4742349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4744349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4745349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4746349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4747349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4748349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4749349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4750349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
47747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
47757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
47767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
47777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4786dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4787f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4788f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4789f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4790f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4796