ACodec.cpp revision 1faa41704e0b976e546321effcb09a85767d51ba
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
366933a4d3339ebbcd34a7f97b9e7350ec74b5ec29cRobert Shih      mIsConfiguredForAdaptivePlayback(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
3748bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang      mRepeatFrameDelayUs(-1ll),
3758bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang      mMaxPtsGapUs(-1l) {
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
377c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
390dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4345778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4397a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
477054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
511308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
512308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
520308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
522308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
526ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
548eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
549eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
564054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5903c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6233c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
62629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
641b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    // FIXME: assume that surface is controlled by app (native window
642b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    // returns the number for the case when surface is not controlled by app)
6431faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6441faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
645b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar
646b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    // Use conservative allocation while also trying to reduce starvation
647b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    //
648b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
649b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    //    minimum needed for the consumer to be able to work
650b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
651b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    //    the consumer
6521faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6531faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
654b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        OMX_U32 newBufferCount =
655b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
657258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
658258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
659258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
660b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        if (err == OK) {
661b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar            *minUndequeuedBuffers += extraBuffers;
662b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar            break;
663b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        }
664b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar
665b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        ALOGW("[%s] setting nBufferCountActual to %lu failed: %d",
666b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar                mComponentName.c_str(), newBufferCount, err);
667b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        /* exit condition */
668b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar        if (extraBuffers == 0) {
669258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
670258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
671258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
672258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
67729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
682054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
684054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
685054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
686054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
687054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
689054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
693b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
700054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7018ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7021e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
70974006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
71074006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
71274006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
71374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
71474006804065941841883c4b46ee785070164023fJamie Gennis
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
71929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
72074006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72474006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
72574006804065941841883c4b46ee785070164023fJamie Gennis
7263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
73874006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
759b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8201e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
829f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8308ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8311e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8331e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
83429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
835c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
836c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
854054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
869d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
870d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
871d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
873d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
874d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
875d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
876d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
877d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
878d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
879054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
880054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
881d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
882d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9072ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9082ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9092ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9102ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
938f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9682944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9692944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9702944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9712944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
978729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
979729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
980c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
981c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
982c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
983c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
99094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
99194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
99294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
99394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
994ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
995ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
998ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
999ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10345ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1073308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1074308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1075d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1113308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1114308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1115308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1116308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1117308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1119308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1120308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1121308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1122308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1125a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1126a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1127a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1128a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1129a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1130a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
11318bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang
11328bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11338bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang            mMaxPtsGapUs = -1l;
11348bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang        }
1135308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1137054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1141054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1142933a4d3339ebbcd34a7f97b9e7350ec74b5ec29cRobert Shih    mIsConfiguredForAdaptivePlayback = false;
1143054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1144054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1145054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1147054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1170fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1171fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1172fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1187933a4d3339ebbcd34a7f97b9e7350ec74b5ec29cRobert Shih                mIsConfiguredForAdaptivePlayback = (err == OK);
1188fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1190054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1191054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1192054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1193054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1194933a4d3339ebbcd34a7f97b9e7350ec74b5ec29cRobert Shih            mIsConfiguredForAdaptivePlayback = true;
1195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11970167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11980167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11990167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12000167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12010167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1204308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
121642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
121742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
121842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
121942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
122042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
122142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
122242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
122342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
122442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
122542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
122642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
122742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
122842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1235aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1236ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1238ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1239aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1240aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1241aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1242ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1243ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12444471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12454471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1247729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1249729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1251729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1252729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1253729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1254729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1255729de186450f78c099637e1fce743fe531862c52Andreas Huber
1256729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1271516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1272516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1275516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1276516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1277516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1280516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1281516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1282516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1286516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1287516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1289ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1290ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1291ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1292ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1293ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1294ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1295ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1296ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1297ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1299729de186450f78c099637e1fce743fe531862c52Andreas Huber
13004471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13014471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13024471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13034471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13058b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13068b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13079806555d3930be43e11106281dee354820ac1c88Andreas Huber
13088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13129806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13139806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13149806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13159806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13169806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13179806555d3930be43e11106281dee354820ac1c88Andreas Huber
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1392aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1393aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1394ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1395ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1397ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1458aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1484ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1485ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1486ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1487ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1540729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1541729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1545729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1546729de186450f78c099637e1fce743fe531862c52Andreas Huber
1547729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1548729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1549729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1550729de186450f78c099637e1fce743fe531862c52Andreas Huber
1551729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1556729de186450f78c099637e1fce743fe531862c52Andreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1560729de186450f78c099637e1fce743fe531862c52Andreas Huber
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1565729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber
15742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1602729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1605729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1606729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1614729de186450f78c099637e1fce743fe531862c52Andreas Huber
1615729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1616729de186450f78c099637e1fce743fe531862c52Andreas Huber
1617729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1619729de186450f78c099637e1fce743fe531862c52Andreas Huber
1620729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1621729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1622729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1623729de186450f78c099637e1fce743fe531862c52Andreas Huber
1624729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1627729de186450f78c099637e1fce743fe531862c52Andreas Huber
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1640729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber
1642c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1643c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1644729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
173494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
173594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
195189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
195289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
195389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
195489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
195589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
201396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
201496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
201596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
201696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
201796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
201896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
201996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
202096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
202196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
202996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
203096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
209496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
211096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
211196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
217096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
218696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
218796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22407c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22417c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22427c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
228496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
228789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
228889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
228989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
229089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
229189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
229289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
229389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
229489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
229589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
229689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
229789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
232596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
233896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2417d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2418d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2419d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2420d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2421d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2422d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2423d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2424d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2425d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2426d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2427d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2428d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2429d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2430d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24317e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24457e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2450b635b0e66b257ab442e230bca96afd5105cf6829Lajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
24517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2452c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2453c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2454c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2455c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2496577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
249731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
249831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
249931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
250031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
250131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
250231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
250331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
250431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
250531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
250631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
250731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
250831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
250931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
251031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
251131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
251231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
251331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
251431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
252531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
252631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
252731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2561577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2562577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2563577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2564577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2565577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2566577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
256831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
256931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
257031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
257131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
257231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
257331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
257431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
257531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
258814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
259114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
259214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
259314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
259414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
259514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
259614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
260614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
260714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
260814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
261114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
261214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
261314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26219806555d3930be43e11106281dee354820ac1c88Andreas Huber
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26449806555d3930be43e11106281dee354820ac1c88Andreas Huber
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
268531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
268631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
268731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
268831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
268931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
269031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
269131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
269231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
269331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
269431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
269531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
269631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26975778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2698cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2699cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2700cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2702cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2703cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2704cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
273887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
273987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
274087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
274187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
274287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
274387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
27751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
27761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28191e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2852eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2853eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2854eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2855496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2856496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2857496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2858496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2859496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2860496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2861496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2862496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2863496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2864496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2865496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2866496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2867496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2868496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2869496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2870496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2871496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2872496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2873eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2874eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2875eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2876eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2877eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2878eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2879eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2880eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2881eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2882eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2883eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2884eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2885eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2886eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2887eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2888eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2889eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2890eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2891eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2892eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2898f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2929ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2930ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2931ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2932ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2933ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2934ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2935ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29620af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3027cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3034349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3035349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3044d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3048d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3050d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
305196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
305296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
305396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30932d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3112a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3115a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31187fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31207fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
31217fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
31227fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
31237fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
31247fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31257fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31263831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31272d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3145dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3146dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3147dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3148dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3180078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
31813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3182078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3186078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3187d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3188d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3189d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3190d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3192078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3193d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3194078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3195349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3205054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3207054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3209054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3212054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3213054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3214054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3215054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3216054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3238dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3240dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3241dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3242dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3244dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3245dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3248349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3249349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3262dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3266b2be2f2e41d5502d79636b21cbad23f4f983bbd7Robert Shih
3267b2be2f2e41d5502d79636b21cbad23f4f983bbd7Robert Shih        default:
3268b2be2f2e41d5502d79636b21cbad23f4f983bbd7Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3269b2be2f2e41d5502d79636b21cbad23f4f983bbd7Robert Shih            break;
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3313d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3314d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3315d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3316d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3317d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3318d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3319d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3320d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3321d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3322d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3323d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3324d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3325d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3326d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3327d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3328d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3348349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
335631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3357577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3358577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3359577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3360e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3361577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3365308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3367308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3368308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3369308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3370308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3371308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3372308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3373496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
337421ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3375496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3376496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3377496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
337921ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
33828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
33838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
33845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
33875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33892d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3405dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3435577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3436577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3437577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3438577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3439577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3440577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3441577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
34446aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
34456aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34511e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3452cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3453cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3455cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3456cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3489c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3490349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3491c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3492c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3494c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3495c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3513f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3519ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3520ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3521ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3522ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3523ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3524ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3525ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3526ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3527ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3528ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3529ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3530308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3531ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3565c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3575c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3603ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3604ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3605ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3606ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3607ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3608ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3609ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3610ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3611ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3612e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3617d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3619e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3620e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3621e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3622afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3623e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3624e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3625e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3626afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3640e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
36441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
36451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3648e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3649e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3651078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3652078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3653078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3655078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36601065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36611065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36621065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36631065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3664c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3671c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3672cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3674c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3676ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3680ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3681ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3682ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3683ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
36840167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3685ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3686ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3687afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3712f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3713f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3714f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3715f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3716f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3717054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3718054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3719a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3720933a4d3339ebbcd34a7f97b9e7350ec74b5ec29cRobert Shih    mCodec->mIsConfiguredForAdaptivePlayback = false;
3721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3739c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3740c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3791c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3810c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3811c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3812c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3818386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38211173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38221173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38231173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38241ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38251ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38261ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38271ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
38457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
38467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3852a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3853a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3854a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3855a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3856a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3857a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3858a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3859a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3860a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3861a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3862a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3863a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3864a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3865a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3866a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3867a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3868a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38698bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
38708bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang        err = mCodec->mOMX->setInternalOption(
38718bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                mCodec->mNode,
38728bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                kPortIndexInput,
38738bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
38748bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                &mCodec->mMaxPtsGapUs,
38758bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
38768bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang
38778bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang        if (err != OK) {
38788bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
38798bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                  mCodec->mComponentName.c_str(),
38808bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang                  err);
38818bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang        }
38828bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang    }
38838bd4d16aa5636e98522c07ae31236420788aa749Chong Zhang
38847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
38937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
38947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
38957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
38967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
38977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3898c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
39153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3918cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
391929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3920cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3921cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3922cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
39235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
392491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
392591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3926cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
39606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
40023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4013d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4014d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4015d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4016d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4017d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4018d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4019d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4020d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4021d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4022d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4023d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4024d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4025d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4026d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4027d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4028d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
40296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4061f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4062349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4063349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4066f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4073054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4074054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4075054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4076054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4077054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4078054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4079054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4080054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4081054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
40824dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
40834dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
40844dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4085054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4103349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4104349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4113c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4120349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
41213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4122349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4123349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4124349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4125349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4126349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4134349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4135349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4150c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4151c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4152c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4153c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4154c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4155c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4156c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4157349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4158349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41717a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4172d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4173d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4174d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4175d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4176d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4177d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4178d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4179349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4180349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4199496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4200496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4201496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4202496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4203496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4204496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4205496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4206496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4207496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4208496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4211a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4217a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4218a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4219a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4220a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4221a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4222a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4223a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4224a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4225a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
42334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
42354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
42364dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
42374dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
42384dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
42394dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
42404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
42414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
42424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
42434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
42444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
42454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4255a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4256530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4258a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4260a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4261a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4262a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4263a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4264a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4265a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4266a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4267a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4268a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4269a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4270a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4271a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4272a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4273a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4274a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4275a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4276e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4277e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4278e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4279e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4280b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4281b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4282e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4283e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4284e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4285e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4286b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4287b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4288b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4289b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4290b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4291b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4292b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4293b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4294b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4295b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4296b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4297b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4298b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4299b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4300b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4301b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4302e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4303e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4304a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4305a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4306a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43076507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
43086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
43096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
43106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
43116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
43126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
43136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
43146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
43156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
43166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
43176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4326054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
433531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
433631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
43383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4362f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4380349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4382349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4384349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4385349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
44003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4423cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4424cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
442529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4426cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4427cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4428cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4430d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4431755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4432755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4433755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4434755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4435755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4436755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4437755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4438755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4439cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
444631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4451349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4453349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
44705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
44715778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
45033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
450431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
450631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
45185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
45375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45450167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
45460167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4574f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
46073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
46353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
46677a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4668d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4669d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4678e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4679e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4680e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4681e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4682e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4695349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4696349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4697349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4698349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4699349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4700349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4701349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4702349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4704349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4705349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4706349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4707349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4708349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4709349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4710349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
47347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
47357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
47367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
47377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4745dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4746dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4747f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4748f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4749f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4750f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4756