ACodec.cpp revision 4dd0a8a3d66c2853faf2834565b3c5df4f68734d
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
388dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4377a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4554dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4564dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
467f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
475054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
476054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
504afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
505afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
510308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
518308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
519308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
520308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
526ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
527ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
546eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
547eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
548eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
562054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5883c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5893c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5915ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6213c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
62429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
628054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
630258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
63429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
642054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
643054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
64929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
651258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
65929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6828ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6831e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
69074006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
69174006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
69374006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
69474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
69574006804065941841883c4b46ee785070164023fJamie Gennis
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70174006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
70674006804065941841883c4b46ee785070164023fJamie Gennis
7073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
71974006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8108ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8111e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8131e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
81429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
815c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
816c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
850d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
853d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
854d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
855d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
861d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
862d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
882349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8872ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8882ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8892ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9482944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9492944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9502944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9512944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
958729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
959729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
960c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
961c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
962c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
963c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
97094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
97194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
97294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
97394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
974ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
975ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
978ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
979ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10145ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1053308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1054308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1056308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1057308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1058308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1105a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1106a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1107a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1108a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1109a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1110a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11690167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11700167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11710167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11720167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11730167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11740167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1177308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
119042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
119142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
119242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
119342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
119442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
119542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
119642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
119742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
119842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
119942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
120042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
120142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1208aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1210ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1212aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1213aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1214aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12174471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12184471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1220729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1222729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1224729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1225729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1226729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1227729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1228729de186450f78c099637e1fce743fe531862c52Andreas Huber
1229729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1244516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1245516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1248516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1249516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1253516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1254516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1255516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1259516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1260516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1262ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1263ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1264ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1265ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1266ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1267ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1268ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1269ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1270ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1272729de186450f78c099637e1fce743fe531862c52Andreas Huber
12734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12764471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12809806555d3930be43e11106281dee354820ac1c88Andreas Huber
12818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12859806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12869806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12879806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12889806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12899806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12909806555d3930be43e11106281dee354820ac1c88Andreas Huber
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1365aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1366aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1367ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1368ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1369ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1370ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1431aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1457ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1460ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1461ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1516729de186450f78c099637e1fce743fe531862c52Andreas Huber
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1518729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber
1520729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1522729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber
1524729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1538729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1539729de186450f78c099637e1fce743fe531862c52Andreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1545729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1546729de186450f78c099637e1fce743fe531862c52Andreas Huber
15472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1575729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1600729de186450f78c099637e1fce743fe531862c52Andreas Huber
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1605729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1606729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1614729de186450f78c099637e1fce743fe531862c52Andreas Huber
1615c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1616c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1617729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber
1619729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1620729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1621729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1622729de186450f78c099637e1fce743fe531862c52Andreas Huber
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
170794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
170894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
192489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
192589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
192689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
192789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
192889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
198696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
198796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
198896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
198996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
199096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
199196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
199296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
199396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
199496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
200296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
200396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
208496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
216096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22137c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22147c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22157c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
226089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
226189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
226289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
226389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
226489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
226589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
226689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
226789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
226889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
226989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
227089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
229896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2391d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2392d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2393d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2394d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2395d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2396d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2397d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2398d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2399d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2400d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2401d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2402d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2403d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24047e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24187e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2437c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2438c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2439c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2440c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2481577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
248231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
248331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
248431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
248631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
248731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
248831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
249031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
249131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
249231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
249331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
249431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
249531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
249631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
249731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
249831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
249931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
251031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
251131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
251231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2546577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2547577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2548577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2549577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2550577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2551577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
255331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
255431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
255531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
255631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
255731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
255831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
255931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
256031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
257314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
257614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
257714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
257814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
257914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
258014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
258114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
259114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
259214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
259314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
259614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
259714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
259814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26069806555d3930be43e11106281dee354820ac1c88Andreas Huber
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26299806555d3930be43e11106281dee354820ac1c88Andreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
267031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
267131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
267231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
267331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
267431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
267531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
267631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
267731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
267831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
267931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
268031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
268131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2683cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2684cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2685cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2687cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2688cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2689cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
272387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
272487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
272587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
272687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
272787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
272887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
27601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
27611e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27891e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2837eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2838eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2839eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2840496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2841496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2842496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2843496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2844496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2845496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2846496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2847496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2848496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2849496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2850496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2851496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2852496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2853496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2854496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2855496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2856496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2857496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2858eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2859eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2860eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2861eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2862eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2863eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2864eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2865eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2866eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2867eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2868eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2869eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2870eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2871eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2872eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2873eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2874eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2875eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2876eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2877eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2878f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2883f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2914ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2915ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2916ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2917ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2918ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2919ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2920ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29450af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3020349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
303696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
303796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
303896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30782d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30942d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3097a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30992d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3100a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
31067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
31077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
31087fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
31097fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31113831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31122d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3130dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3131dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3132dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3133dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3157d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3158d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3159d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3165078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
31663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3167078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
31705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3171078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3177078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3178d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3179078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3180349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3181d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3182d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3183d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3184d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3185d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3186d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3190054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3194054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3198054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3199054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3200054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3201054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3223dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3225dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3226dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3227dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3229dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3230dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3233349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3234349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3247dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32955778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3296349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3304d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3305d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3306d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3307d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3308d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3309d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3310d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3311d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3312d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
334131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3342577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3343577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3344577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3346577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3349308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3350308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3351308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3352308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3353308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3354308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3355308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3356308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3357308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
335921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3360496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3361496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3362496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
336421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
33678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
33688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33742d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3420577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3421577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3422577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3423577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3424577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3425577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3426577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
34296aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
34306aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3437cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3438cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3440cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3441cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3474c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3476c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3477c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3479c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3480c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3498f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3504ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3505ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3506ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3507ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3508ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3509ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3510ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3511ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3512ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3513ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3514ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3515308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3516ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3542c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3543c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3544c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3550c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3560c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3572c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3573c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3574c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3575c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3588ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3589ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3590ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3591ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3592ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3593ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3594ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3595ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3596ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3597e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3602d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3604e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3605e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3606e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3607afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3608e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3609e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3610e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3611afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3625e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
36291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
36301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3633e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3634e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3636078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3637078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3638078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3640078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3649c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3656c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3657cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3659c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3661ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3665ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3666ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3667ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3668ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
36690167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3670ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3671ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3672afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3692c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3695c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3697f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3698f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3699f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3700f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3701f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3702054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3703054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3704a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3705054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
37905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3794c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3795c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3796c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3802386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38041173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38051173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38061173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38071173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38081ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38091ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38101ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38111ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
38297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
38307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3836a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3837a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3838a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3839a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3840a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3841a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3842a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3843a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3844a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3845a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3846a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3847a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3848a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3849a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3850a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3851a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3852a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
38627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
38637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
38647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
38657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
38667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3867c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3879f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
38843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3887cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
388829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3889cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3890cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3891cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
389391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
389491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3895cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
39296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39326463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39336463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39346463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39356463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39366463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
39713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3982d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3983d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3984d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3985d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3986d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3987d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3988d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3989d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3990d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3991d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3992d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3993d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3994d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3995d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3996d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3997d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
39986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4031349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4032349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4035f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4042054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4043054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
40514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
40524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
40534dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4054054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4055054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4056054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4072349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4073349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4082c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4083054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4084054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4089349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
40903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4092349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4093349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4094349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4119c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4120c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4121c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4122c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4123c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4124c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4125c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4126349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4127349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4141d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4142d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4143d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4144d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4145d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4146d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4147d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4148349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4149349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4167496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4168496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4169496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4170496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4171496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4172496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4173496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4174496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4175496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4176496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4177496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4178a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4180a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4181a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4182a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4183a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4184a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4185a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4186a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4187a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4188a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4189a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4190a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4191a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
41976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
41997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
42024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
42044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
42054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
42064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
42074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
42084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
42094dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
42104dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
42114dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
42124dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
42134dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
42144dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4224a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4225530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4226a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4227a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4228a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4229a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4230a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4231a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4232a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4233a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4234a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4235a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4236a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4237a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4238a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4239a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4240a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4241a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4242a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4243a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4244a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4245e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4246e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4247e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4248e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4249b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4250b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4251e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4252e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4253e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4254e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4255b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4256b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4257b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4258b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4259b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4260b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4261b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4262b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4263b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4264b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4265b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4266b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4267b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4268b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4269b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4270b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4271e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4272e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4273a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4274a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4275a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42766507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
42776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
42786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
42796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
42806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
42816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
42826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
42836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
42846507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
42856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
42866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
429431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4295054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4301349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
430431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
430531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
43073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4326f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4331f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4349349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4351349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4353349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4354349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
43693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4392cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4393cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
439429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4395cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4396cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4397cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4399d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4400755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4401755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4402755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4403755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4404755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4405755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4406755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4407755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4408cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
441531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4419349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4420349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4421349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4422349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
44723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
447331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
447531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
44875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4493349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4494349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4495349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4496349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4497349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4498349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4499349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45040af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
45065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45140167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
45150167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4517bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4518bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4519bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4520bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4543f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
45763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4599f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
46043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
46367a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4637d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4638d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4647e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4648e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4649e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4650e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4651e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4663349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4664349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4665349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4666349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4671349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4674349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4675349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4676349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4677349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4678349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4679349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
47037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
47047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
47057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
47067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4715dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4716f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4717f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4718f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4719f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4725