ACodec.cpp revision 6fbc1afd36f514f8b8d36ce67f5e69776c690bd2
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
206fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar#include <utils/Trace.h>
216fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
32afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
40f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4345778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4397a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
468054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
469054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
492ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
496afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
497afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
499308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
500308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
506ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
510308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
537eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
542eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
545eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
552054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
553054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5815ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5843c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5853c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6113c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
621054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
630258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
664054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6728ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6731e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
68074006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
68174006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68374006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68574006804065941841883c4b46ee785070164023fJamie Gennis
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
69029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
69174006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69574006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69674006804065941841883c4b46ee785070164023fJamie Gennis
6973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70974006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
712054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
713054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
799f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8008ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
805c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
806c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
840d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
847d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
848d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
851d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8792ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8802ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
908f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9402944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9412944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
948729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
949729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
952c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
953c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
96294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
964ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
965ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
968ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
969ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1043308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1050308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1113fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1114fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1115fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1116fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1117fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1118fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1119fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1120fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1121fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1122fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1144d411b4ca2945cd8974a3a78199fce94646950128Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11620167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11630167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11640167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1167308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
117942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
118042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
118142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
118242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
118342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
118442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
118542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
118642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
118742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
118842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
119042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
119142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1198aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1200ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1203aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1204aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1206ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12074471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12084471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1210729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1212729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1214729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1215729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1217729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1218729de186450f78c099637e1fce743fe531862c52Andreas Huber
1219729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1234516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1235516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1238516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1239516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1240516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1244516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1245516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1249516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1252ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1253ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1254ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1255ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1256ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1257ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1258ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1259ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1260ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber
12634471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12644471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12709806555d3930be43e11106281dee354820ac1c88Andreas Huber
12718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12759806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12769806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12779806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12789806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12799806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12809806555d3930be43e11106281dee354820ac1c88Andreas Huber
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1355aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1356aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1358ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1359ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1360ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
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        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1421aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1503729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1504729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber
15372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1565729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1568729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1600729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber
1605c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1606c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
169794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
169894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
191589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
191689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
191789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
191889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
197696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
197796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
197896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
197996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
198096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
198196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
198296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
198396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
198496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
199396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
207396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
207496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
213396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
215096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22037c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22047c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22057c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
225189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
225289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
225389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
225489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
225589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
225689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
225789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
225889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
225989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
226089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
228796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
228896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
230196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2380d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2381d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2382d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2383d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2384d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2385d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2386d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2387d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2388d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2389d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2390d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2391d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2392d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2393d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23947e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24087e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2427c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2428c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2429c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2430c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2471577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
247231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
247331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
247431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
247531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
247631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
247731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
247831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
247931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
248031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
248131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
248231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
248431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
248631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
248731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
248831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
248931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
250031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
250131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
250231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2536577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2537577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2538577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2539577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2540577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2541577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
254331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
254431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
254531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
254631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
254831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
254931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
255031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
256314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
256614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
256714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
256814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
256914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
257014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
257114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
258114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
258214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
258314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
258614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
258714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
258814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25969806555d3930be43e11106281dee354820ac1c88Andreas Huber
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26199806555d3930be43e11106281dee354820ac1c88Andreas Huber
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
266031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
266131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
266231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
266431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
266531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
266631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
266831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
267031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
267131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26725778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2673cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2674cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2675cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2677cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2678cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2679cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
271387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
271487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
271587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
271687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
271787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
271887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
27501e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
27511e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27791e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27941e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2827eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2828eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2829eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2830496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2831496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2832496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2833496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2834496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2835496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2836496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2837496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2838496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2839496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2840496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2841496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2842496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2843496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2844496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2845496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2846496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2847496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2848eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2849eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2850eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2851eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2852eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2853eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2854eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2855eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2856eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2857eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2858eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2859eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2860eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2861eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2862eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2863eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2864eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2865eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2866eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2867eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2868f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2873f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2904ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2905ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2906ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2907ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2908ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2909ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2910ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29430af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29440af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3002cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3009349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3010349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3024d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3025d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
302696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
302796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
302896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30682d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30842d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3087a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30892d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3090a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
30947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
30957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
30967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
30977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
30987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
30997fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31007fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31013831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31022d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3120dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3121dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3122dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3123dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3148d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3149d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
31563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3157078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
31595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
31605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3161078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3164d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3165d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3167078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3168d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3169078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3170349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3176d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3177d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3190054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3213dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3215dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3216dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3217dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3219dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3220dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3224349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3237dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3286349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3302d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3303d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3309054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
333131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3332577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3333577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3334577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3336577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3340308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3341308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3342308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3343308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3344308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3345308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3346308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3347308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
334921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
335421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
33578b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
33588b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33642d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
33775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3380dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3410577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3411577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3412577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3413577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3414577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3415577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3416577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
34196aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
342079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
34216fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        ATRACE_NAME("render");
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34271e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3428cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3429cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3431cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3432cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
34346fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        if (mCodec->mNativeWindow != NULL &&
34356fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            (info->mData == NULL || info->mData->size() != 0)) {
34366fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar            ATRACE_NAME("frame-drop");
34376fbc1afd36f514f8b8d36ce67f5e69776c690bd2Lajos Molnar        }
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3467c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3469c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3470349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3471c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3472c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3474c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3475c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3493f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3499ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3500ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3501ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3502ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3503ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3504ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3505ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3506ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3507ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3508ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3509ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3510308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3511ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3538c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3539c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3545c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3555c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3567c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3568c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3570c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3573c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3576c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3584ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3585ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3586ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3587ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3588ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3589ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3590ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3591ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3592e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3597d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3599e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3600e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3601e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3602afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3603e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3604e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3605e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3606afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3620e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
36241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
36251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3628e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3629e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3631078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3632078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3633078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3635078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3644c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3651c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3652cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3654c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3656ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3660ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3661ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3662ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3663ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
36640167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3665ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3666ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3667afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3692f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3693f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3694f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3695f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3696f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3698054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3699a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3700054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3789c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3790c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3791c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3797386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37991173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38001173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38011173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38021173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38031ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38041ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38051ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38061ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
38247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
38257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3831a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3832a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3833a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3834a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3835a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3836a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3837a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3838a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3839a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3840a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3841a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3842a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3843a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3844a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3845a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3846a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3847a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
38577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
38587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
38597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
38607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
38617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3862c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
38793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3882cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
388329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3884cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3885cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3886cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
388891bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
388991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3890cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
39246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39296463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39306463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39316463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3961f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
39663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3977d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3978d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3979d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3980d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3981d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3982d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3983d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3984d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3985d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3986d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3987d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3988d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3989d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3990d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3991d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3992d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
39936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4025f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4026349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4027349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4036054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4037054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4039054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4042054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4043054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4044054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4045054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4046054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4048054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4064349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4065349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4074c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4077054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4081349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
40823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4083349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4084349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4085349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4086349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4087349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4112c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4113c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4114c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4115c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4117c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4118349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4119349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41327a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4133d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4134d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4135d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4136d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4137d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4138d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4139d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4140349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4141349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4164496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4165496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4166496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4167496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4168496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4169496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4170a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4171a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4173a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4174a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4175a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4176a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4177a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4178a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4180a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4181a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4182a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4183a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4184a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4185a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4186a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
41896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
41917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
41927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4203a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4204530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4211a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4224e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4225e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4226e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4227e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4228b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4229b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4230e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4231e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4232e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4233e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4234b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4235b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4236b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4237b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4238b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4239b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4240b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4241b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4242b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4243b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4244b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4245b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4246b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4247b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4248b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4249b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4250e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4251e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4252a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4253a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42556507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
42566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
42576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
42586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
42596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
42606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
42616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
42626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
42636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
42646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
42656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4274054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
428331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
428431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
42863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4310f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
43483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4371cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4372cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
437329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4374cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4375cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4376cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
43775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4378d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4379755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4380755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4381755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4382755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4383755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4384755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4385755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4386755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4387cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
439431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4399349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4400349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4401349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
44185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
44195778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
44513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
445231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
445431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
44665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4472349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4473349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4474349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4475349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4476349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4477349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
44830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
44855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44930167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
44940167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4495bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4496bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4497bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4498bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4499bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4500bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4501bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
45553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4566c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4578f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
45833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
46157a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4616d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4617d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4626e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4627e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4628e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4629e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4630e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4642349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4643349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4644349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4645349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4646349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4647349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4648349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4649349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4650349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4652349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4653349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4654349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4655349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4656349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4658349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
46827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
46837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
46847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
46857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4693dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4694dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4695f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4696f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4697f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4698f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4704