ACodec.cpp revision 72cecca17d735db6532c45f0a7e10c47ee6f065a
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
36875832930a28fd70f6fc683ed966477ceea810668Robert Shih      mIsConfiguredForAdaptivePlayback(false),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3719806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
37772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMaxPtsGapUs(-1l),
37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
380c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
393dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
398f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
401f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4175778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4235778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4375778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4427a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
457496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
506ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
510afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
514308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
515308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
524308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
525308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
527ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
551eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
560eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
566054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
567054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
568054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6003c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6263c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
62929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
633054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
636054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
63929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
646258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
647054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
648054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
649258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
651258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
652258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
65429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
657258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
658258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
659258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
66429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
683054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
686054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6878ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
69029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
69574006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
69674006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
697054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
69874006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
69974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
70074006804065941841883c4b46ee785070164023fJamie Gennis
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70674006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
71074006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
71174006804065941841883c4b46ee785070164023fJamie Gennis
7123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
72474006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
814f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8158ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8161e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
817054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8181e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
81929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
820c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
821c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
853054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
854d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
855d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
859d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
861d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
862d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
863d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
866d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
867d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
887349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8932ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8942ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8952ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
923f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9532944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9542944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9552944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9562944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
963729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
964729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
965c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
966c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
967c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
968c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
97594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
97694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
97794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
97894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
979ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
980ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
983ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
984ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
985774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
986774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
98797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
98897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10235ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1062308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1063308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1065308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1066308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1067308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1069308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1113308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1117a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1118a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1119a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
112094ee4b708acfa941581160b267afb79192b1d816Chong Zhang
112194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
112294ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mMaxPtsGapUs = -1l;
112394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
112472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
112572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
112672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
112772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
112872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
112972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1132054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1133054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1135054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
113775832930a28fd70f6fc683ed966477ceea810668Robert Shih    mIsConfiguredForAdaptivePlayback = false;
1138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1141054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1142054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1170fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1171fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1172fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
118275832930a28fd70f6fc683ed966477ceea810668Robert Shih                mIsConfiguredForAdaptivePlayback = (err == OK);
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
118975832930a28fd70f6fc683ed966477ceea810668Robert Shih            mIsConfiguredForAdaptivePlayback = true;
1190054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11910167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11920167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11930167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11940167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11950167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1198054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1199308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
121142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
121242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
121342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
121442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
121542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
121642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
121742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
121842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
121942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
122042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
122142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
122242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
122342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1230aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1232ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1234aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1235aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1236aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1238ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12394471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12404471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1242729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1244729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1246729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1247729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1248729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1249729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1250729de186450f78c099637e1fce743fe531862c52Andreas Huber
1251729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1266516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1267516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1270516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1271516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1272516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1275516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1276516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1277516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1281516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1282516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1284ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1285ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1286ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1287ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1288ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1289ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1290ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1291ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1292ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
129397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
129497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
129597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
129697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
129797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
129897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
129997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
130097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
130197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1303729de186450f78c099637e1fce743fe531862c52Andreas Huber
13044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13074471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13108b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13119806555d3930be43e11106281dee354820ac1c88Andreas Huber
13128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13169806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13179806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13189806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13199806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13209806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13219806555d3930be43e11106281dee354820ac1c88Andreas Huber
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1396aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1397aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1398ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1399ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1400ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1401ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1462aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1491ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1492ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
152097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
152197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
152397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
152497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
152597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
152797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
152897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
153097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
153197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
153297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
153397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
153497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
153597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1614729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1615729de186450f78c099637e1fce743fe531862c52Andreas Huber
16162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16332f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1644729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber
1666729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1667729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1668729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1669729de186450f78c099637e1fce743fe531862c52Andreas Huber
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1676729de186450f78c099637e1fce743fe531862c52Andreas Huber
1677729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1678729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1681729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1682729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1683729de186450f78c099637e1fce743fe531862c52Andreas Huber
1684c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1685c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1690729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1691729de186450f78c099637e1fce743fe531862c52Andreas Huber
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
177694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
177794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
199489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
199589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
199689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
199789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
205696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
205796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
205896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
205996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
206096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
206196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
206296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
206396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
207196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
207296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
213696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
215396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
222896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
222996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22827c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22837c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22847c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
232989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
233089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
233189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
233289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
233389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
233489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
233589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
233689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
233789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
233889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
233989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
236696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
236796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
238096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2460d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2461d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2462d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2463d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2464d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2465d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2466d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2467d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2468d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2469d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2470d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2471d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2472d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24737e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24877e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
25007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
25027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
25057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2506c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2507c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2508c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2509c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
25107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2550577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
255131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
255231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
255331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
255431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
255531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
255631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
255731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
255831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
255931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
256031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
256131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
256331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
256531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
256631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
256731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
256831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
257931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
258031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2615577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2616577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2617577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2618577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2619577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2620577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
262231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
262331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
262431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
262531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
262631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
262731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
262831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
262931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
263097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
264214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
264514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
264614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
264714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
264814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
264914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
265014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
266014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
266114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
266214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
266514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
266614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
266714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26759806555d3930be43e11106281dee354820ac1c88Andreas Huber
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26989806555d3930be43e11106281dee354820ac1c88Andreas Huber
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
273697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
273797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
273897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
273997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
274097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
274197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
274297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
274397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
274497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
274597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
274697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
274797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
274897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
274997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
275097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
275197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
275297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
275731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
275831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
275931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
276031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
276131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
276231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
276331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
276431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
276531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
276631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
276731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
276831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27695778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2770cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2771cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2772cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2774cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2775cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2776cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
281087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
281187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
281287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
281387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
281487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
281587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28481e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2861bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2862bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2890bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28911e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2896bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2897bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2898bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2924eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2925eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2926eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2927496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2928496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2929496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2930496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2931496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2932496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2933496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2934496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2935496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2936496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2937496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2938496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2939496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2940496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2941496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2942496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2943496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2946eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2947eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2948eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2949eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2950eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2951eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2952eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2953eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2954eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2955eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2956eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2957eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2958eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2959eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2960eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2961eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2962eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2963eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2964eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2965f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2970f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
30007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3001ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3002ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3003ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3004ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3005ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3006ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3007ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
30320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
30330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
30340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
30350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
30360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
30370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
30380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
30390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
30400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
30410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3099cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
31053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3106349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3121d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3122d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
312396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
312496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
312596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3126d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3127d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3128d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31812d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3184a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3187a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31907fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
31937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
31947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
31957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
31967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31983831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31992d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3217dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3218dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3219dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3220dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
32395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3243d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3244d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3245d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3246d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3252078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3254078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3258078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3264078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3265d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3266078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3268d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3269d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3270d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3271d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3272d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3273d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3275054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3276054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3277054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3278054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3279054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3280054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3281054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3283054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3286054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
33035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
33055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
33075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3310dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
33113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3312dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3313dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3314dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
33153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3316dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3317dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3320349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3334dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3338625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3339625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3340625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3341625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33825778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3383349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3390d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3391d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3392d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3393d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3394d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3395d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3396d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3397d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3398d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3399d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3406054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
34185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
34195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3420349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
34235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
34265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
342831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3429577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3430577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3431577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
34324bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3433577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3436308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3437308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3438308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3439308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3440308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3441308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3442308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3443308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3444308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3445496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
344621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3447496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3448496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3449496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
345121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34538b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34612d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3477dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3507577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3508577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3509577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3510577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3511577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3512577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3513577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
35166aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
351779ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
35231e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3524cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3525cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3527cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3528cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3561c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3562349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3563c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3564c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3566c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3567c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3585f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3591ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3592ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3593ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3594ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3595ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3596ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3597ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3598ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3599ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3600ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3601ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3602308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3603ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
36195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
36205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3637c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3647c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3675ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3676ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3677ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3678ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3679ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3680ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3681ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3682ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3683ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3684e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3689d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3691e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3692e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3693e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3694afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3695e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3696e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3697e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3698afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
37045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
37095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3712e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
37161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
37171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
37191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3720e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3721e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3723078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3724078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3725078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
37261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3727078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
37301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
37311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
37321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
37341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
37351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3736c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
37375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
37385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
37395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
37405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
37415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3743c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3744cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3746c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3748ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3752ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3753ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3754ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3755ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37560167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3757ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3758ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3759afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3775c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3776c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3777c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3778c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3779c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3780c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3784f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3785f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3786f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3787f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3788f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3791a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
379275832930a28fd70f6fc683ed966477ceea810668Robert Shih    mCodec->mIsConfiguredForAdaptivePlayback = false;
3793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3800c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
38277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
38297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
38307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
38317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
38327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3839c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3843c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3854c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3859c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3860c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3861c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3862c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3863c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3866c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3867c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3868c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3870c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3882c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3883c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3884c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3890386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38961ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38971ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38981ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38991ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
39045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
39055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
39075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
39105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
39137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
39147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
39157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
39177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
39207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
39217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
39237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3924a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3925a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3926a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3927a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3928a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3929a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3930a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3931a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3932a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3933a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3934a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3935a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3936a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3937a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3938a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
394194ee4b708acfa941581160b267afb79192b1d816Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
394294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
394394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
394494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
394594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
394694ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
394794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
394894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
394994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
395094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
395172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
395272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
395372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang          }
395472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      }
395572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
395672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
395772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
395872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
395972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
396072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
396172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
396272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
396372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
396472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
396572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
396672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
396794ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
396894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
396994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
397094ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
397194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
39727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
39737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
39747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
39757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
39767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
39777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
39787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
39797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
39807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
39817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
39827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
39837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
39847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
39857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
39885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
39905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3998f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
40033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4005cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4006cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
400729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4008cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4009cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4010cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
40115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
401291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
401391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4014cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
402972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
40426463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
40436463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40446463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
40456463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40466463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40476463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
40486463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
40496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
40516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
40526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
40546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4086f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
40913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
409672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4103d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4104d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4105d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4106d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4107d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4108d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4109d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4110d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4111d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4112d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4113d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4114d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4115d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4116d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4117d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4118d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
41196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
41206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
41216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
41236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
41246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4152349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4153349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4156f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
41724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
41734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
41744dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4193349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4194349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4203c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4205054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4207054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4208054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4210349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
42113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4212349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4213349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4214349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4215349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4216349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4224349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4225349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
42293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4245c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4247349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4248349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42617a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4262d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4263d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4264d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4265d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4266d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4267d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4268d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4288496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4289496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4290496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4291496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4292496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4293496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4294496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4295496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4296496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4297496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4298496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4299a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4300a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4301a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4302a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4303a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4304a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4305a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4306a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4307a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4308a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4309a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4310a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4311a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4312a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4313a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4314a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4315a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
43186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
43197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
43207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
43217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43234dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
43244dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
43254dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
43264dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
43274dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
43284dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
43294dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
43304dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
43314dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
43324dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
43334dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
43344dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
43354dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4344a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4345a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4346530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4347a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4348a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4349a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4350a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4351a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4352a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4353a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4354a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4355a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4356a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4357a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4358a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4359a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4360a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4361a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4362a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4363a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4364a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4365a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
436672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
436772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
436872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
436972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
437072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
437172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
437272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
437372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
437472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
437572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
437672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
437772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
437872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
437972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
438072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
438172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4382e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4383e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4384e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4385e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4386b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4387b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4388e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4389e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4390e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4391e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4392b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4393b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4394b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4395b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4396b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4397b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4398b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4399b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4400b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4401b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4402b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4403b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4404b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4405b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4406b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4407b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4408e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4409e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
44136507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
44146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
44156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
44166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
44176507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
44186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
44196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
44206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
44216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
44226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
44236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
443131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4432054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
444131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
444231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
44443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4463f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4468f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4486349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4488349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
44893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4490349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4491349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
45063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4528cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4529cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4530cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
453129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4532cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4533cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4534cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
45355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4536d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4537755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4538755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4539755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4540755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4541755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4542755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4543755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4544755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4545cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
455131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
455231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4556349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4557349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4558349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4559349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
45765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
46093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
461031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
461231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
46245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4631349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4632349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4633349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4634349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4635349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4636349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
46410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
46435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46510167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
46520167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4680f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
47133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4736f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
47413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47737a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4774d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4775d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4784e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4785e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4786e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4787e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4788e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4801349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4802349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4803349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4804349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4805349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4806349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4807349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4808349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
48093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4812349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4813349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4814349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4815349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4816349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
48407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
48417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
48427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
48437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4852dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4853f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4854f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4855f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4856f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4862