ACodec.cpp revision 774eb18c40c3a7da0bc1636a9779f02315ddbad8
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
388dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4377a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
498308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6093c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
67874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
67974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68374006804065941841883c4b46ee785070164023fJamie Gennis
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
68974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69474006804065941841883c4b46ee785070164023fJamie Gennis
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
797f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7988ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
837d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
838d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
842d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
850d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8752ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
946729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
947729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
948c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
949c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
962ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
963ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
966ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
967ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
968774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
969774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10045ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1043308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1045d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1049d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1050308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1099a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1100a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1113fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1114fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1115fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1116fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1117fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1118fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1119fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1120fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1121fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1122fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11620167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11630167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11640167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1167308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
117942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
118042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
118142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
118242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
118342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
118442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
118542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
118642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
118742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
118842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
119042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
119142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1198aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1200ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1203aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1204aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1206ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12074471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12084471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1210729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1212729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1214729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1215729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1217729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1218729de186450f78c099637e1fce743fe531862c52Andreas Huber
1219729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1234516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1235516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1238516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1239516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1240516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1244516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1245516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1249516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1250516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1252ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1253ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1254ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1255ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1256ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1257ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1258ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1259ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1260ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1262729de186450f78c099637e1fce743fe531862c52Andreas Huber
12634471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12644471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12709806555d3930be43e11106281dee354820ac1c88Andreas Huber
12718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12759806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12769806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12779806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12789806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12799806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12809806555d3930be43e11106281dee354820ac1c88Andreas Huber
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1355aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1356aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1358ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1359ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1360ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1421aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1450ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1451ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1503729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1504729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber
15372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1565729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1568729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1600729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber
1605c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1606c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
169794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
169894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
197196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
197296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
197396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
197496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
197596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
197696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
197796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
197896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
197996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
198796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
198896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
206996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
214596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
21987c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
21997c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22007c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
227196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
227296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
228596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2364d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2365d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2366d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2367d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2368d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2369d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2370d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2371d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2372d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2373d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2374d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2375d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2376d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2377d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23787e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
23867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
23877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
23907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23927e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
23937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
23947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
23957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
23987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
23997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2411c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2412c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2413c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2414c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
245631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
245731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
245831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
245931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
246031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
246131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
246231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
246331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
246431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
246531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
246631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
246731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
246831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
246931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
247031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
247131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
247231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
247331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2483e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
248431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
248531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
248631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2488e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2520577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2521577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2522577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2523577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2524577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2525577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
252731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
252831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
252931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
253031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
253131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
253231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
253331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
253431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
254714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
255014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
255114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
255214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
255314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
255414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
255514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
256514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
256614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
256714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
257014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
257114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
257214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25809806555d3930be43e11106281dee354820ac1c88Andreas Huber
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26039806555d3930be43e11106281dee354820ac1c88Andreas Huber
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
264431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
264531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
264631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
264731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
264831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
264931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
265031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
265131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
265231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
265331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
265431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
265531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2657cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2658cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2659cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2661cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2662cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2663cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
269787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
269887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
269987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
270087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
270187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
270287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
27341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
27351e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27631e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27781e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2812eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2813eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2814496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2815496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2816496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2817496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2818496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2819496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2820496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2821496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2822496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2823496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2824496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2825496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2826496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2827496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2828496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2829496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2830496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2831496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2832eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2833eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2834eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2835eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2836eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2837eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2838eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2839eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2840eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2841eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2842eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2843eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2844eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2845eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2846eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2847eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2848eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2849eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2850eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2851eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2852f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2857f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
28867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
28877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2888ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2889ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2890ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2891ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2892ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2893ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2894ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2986cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
29923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3002d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3003d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3004d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3005d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3006d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3007d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3008d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3009d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
301096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
301196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
301296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3013d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3014d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30522d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30682d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3071a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
30725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30732d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3074a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
30783831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
30793831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
30802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3081a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        mode = KEEP_BUFFERS;
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
30855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3099dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3100dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3101dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3102dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3125d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
31353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3136078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
31375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3140078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3146078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3148078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3149349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3150d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3151d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3152d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3153d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3154d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3155d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3156d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
31845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
31875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
31895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
31905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3192dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
31933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3194dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3195dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3196dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
31973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3198dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3199dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3216dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32645778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3267d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3278d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3279d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3281d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3282d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3302349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
331031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3311577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3312577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3313577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3315577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3318308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3319308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3320308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3321308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3322308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3323308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3324308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3325308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3326308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3327496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
332821ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
333321ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
33368b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
33378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
33385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
33415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33432d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
33565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3359dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3389577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3390577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3391577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3392577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3393577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3394577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3395577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
33986aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
33996aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3406cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3407cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3409cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3410cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3441c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3443c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3444349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3445c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3446c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3448c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3449c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3467f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3473ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3474ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3475ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3476ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3477ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3478ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3479ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3480ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3481ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3482ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3483ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3484308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3485ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3510c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3511c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3519c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3529c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3541c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3542c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3543c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3544c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3547c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3557ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3558ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3559ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3560ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3561ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3562ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3563ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3564ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3565ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3566e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3571d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3573e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3574e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3575e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3576afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3577e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3578e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3579e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3580afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
35935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3594e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
35955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
35981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
35991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36011065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3602e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3603e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3605078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3606078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3607078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3609078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3618c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3625c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3626cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3628c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3630ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3634ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3635ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3636ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3637ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
36380167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3639ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3640ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3641afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3666f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3667f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3668f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3669f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3670f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3673a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3692c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3695c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3727c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3731c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3732c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3739c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3740c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3763c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3764c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3765c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3771386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37731173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37741173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37751173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37761173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37771ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37781ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37791ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37801ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
37947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
37957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
37967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
37987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
37997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3805a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3806a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3807a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3808a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3809a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3810a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3811a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3812a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3813a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3814a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3815a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3816a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3817a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3818a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3819a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3820a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3821a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
38317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
38327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
38337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
38347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
38357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
38385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
38405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3848f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
38533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3855cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3856cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
385729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3858cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3859cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3860cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
386291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
386391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3864cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
38916463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
38926463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38936463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
38946463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38956463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38966463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
38976463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
38986463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38996463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39006463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3935f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
39403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3951d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3952d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3953d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3954d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3955d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3956d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3957d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3958d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3959d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3960d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3961d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3962d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3963d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3964d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3965d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3966d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
39676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3999f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4000349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4001349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4011054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4012054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4013054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4014054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4015054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4016054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4017054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4018054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4019054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4020054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4021054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4022054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4038349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4039349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4047054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4048c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4049054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4050054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4051054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4052054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4053054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4055349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
40563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4058349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4059349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4060349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4061349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4069349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4070349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
40743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4087c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4090c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4091c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4092349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4093349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41067a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4107d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4108d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4109d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4110d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4111d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4112d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4113d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4114349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4115349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4133496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4134496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4135496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4136496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4137496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4138496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4139496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4140496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4141496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4142496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4143496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4144a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4145a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4146a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4147a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4150a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4151a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4152a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4153a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4154a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4155a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4156a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4157a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4158a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4159a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4160a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
41636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
41657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
41667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4176a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4177a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4178530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4180a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4181a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4182a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4183a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4184a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4185a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4186a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4187a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4188a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4189a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4190a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4191a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4198e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4199e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4200e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4201e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4202b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4203b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4204e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4205e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4206e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4207e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4208b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4209b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4210b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4211b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4212b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4213b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4214b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4215b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4216b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4217b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4218b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4219b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4220b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4221b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4222b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4223b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4224e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4225e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4226a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4227a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4228a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42296507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
42306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
42316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
42326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
42336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
42346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
42356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
42366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
42376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
42386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
42396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
424731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4248054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
425731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
425831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
42603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4279f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4302349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4304349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4306349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4307349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
43223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4345cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4346cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
434729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4348cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4349cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4350cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
43515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4352d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4353755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4354755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4355755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4356755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4357755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4358755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4359755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4360755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4361cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
436731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
436831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4374349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4375349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
43925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
43935778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
44253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
442631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
442831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
44405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4447349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4448349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4449349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4450349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4451349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4452349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
44570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44670167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
44680167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4469bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4470bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4471bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4472bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4473bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4474bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4475bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4496f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
45293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4540c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4552f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
45573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
45897a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4590d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4591d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4600e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4601e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4602e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4603e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4604e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4617349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4618349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4619349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4620349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4621349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4622349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4623349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4624349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4626349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4627349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4628349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4629349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4630349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4631349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4632349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
46567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
46577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
46587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
46597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4667dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4668dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4669f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4670f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4671f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4672f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4678