ACodec.cpp revision 94ee4b708acfa941581160b267afb79192b1d816
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),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37594ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mMaxPtsGapUs(-1l) {
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
378c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
391dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4155778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4355778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
439f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4407a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
456496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
457496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
470f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
478054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
479054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
480054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
508afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
510afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
512308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
513308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
521308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
522308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
523308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
524308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
525ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
527ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
549eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
550eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
551eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
564054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
565054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
566054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5913c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5923c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5933c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5945ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6243c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
62729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
645054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
646054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
647258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
648258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
649258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
650258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
651258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
65229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
653258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
654258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
655258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
656258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
657258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
66229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
667054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
670054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
671054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
672054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
673054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
674054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
675054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
676054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
677054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
678054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
681054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
684054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6858ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6861e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
69374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
69474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
695054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
69674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
69774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
69874006804065941841883c4b46ee785070164023fJamie Gennis
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
70474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
70874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
70974006804065941841883c4b46ee785070164023fJamie Gennis
7103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
72274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8031e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
812f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8138ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8141e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8161e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
81729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
818c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
819c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
849054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
853d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
854d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
855054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
856d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
857d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
858d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
859d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
860d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
861d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
864d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
865d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8902ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8912ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8922ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8932ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
921f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9512944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9522944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9532944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9542944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
961729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
962729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
963c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
964c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
965c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
966c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
97394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
97494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
97594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
97694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
977ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
978ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
981ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
982ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
983774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
984774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
98597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
98697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10215ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1060308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1061308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1063308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1064308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1065308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1067308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10753a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10763a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10773a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10783a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10793a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10803a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10813a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10823a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10833a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10843a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10853a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10863a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10873a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10883a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10893a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10903a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1094308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1095308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1096308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1097308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1098308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1110308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1111308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1112a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1113a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1114a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1115a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1116a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1117a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
111894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
111994ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
112094ee4b708acfa941581160b267afb79192b1d816Chong Zhang            mMaxPtsGapUs = -1l;
112194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
1122308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1129054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1130054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1131054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1132054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1133054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1152fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1153fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1154fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1155fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1156fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1157fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1158fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1159fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1160fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1161fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1162fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1163fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1164fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1165fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1166fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1167fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1170fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1171fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1172fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11800167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11810167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11820167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11830167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11840167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11850167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1188308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
120042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
120142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
120242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
120342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
120442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
120542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
120642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
120742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
120842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
120942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
121042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
121142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
121242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1219aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1223aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1224aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1225aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1226ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12284471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12294471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1231729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1233729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1235729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1236729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1237729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1238729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1239729de186450f78c099637e1fce743fe531862c52Andreas Huber
1240729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1255516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1256516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1259516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1260516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1261516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1264516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1265516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1266516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1270516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1271516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1273ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1274ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1275ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1276ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1277ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1278ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1279ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1280ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1281ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
128297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
128397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
128497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
128597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
128697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
128797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
128897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
128997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
129097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1292729de186450f78c099637e1fce743fe531862c52Andreas Huber
12934471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12944471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12954471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12964471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12978b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12988b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12998b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13009806555d3930be43e11106281dee354820ac1c88Andreas Huber
13018b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13028b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13038b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13048b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13059806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13069806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13079806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13089806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13099806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13109806555d3930be43e11106281dee354820ac1c88Andreas Huber
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1385aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1386aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1387ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1388ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1390ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1451aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1477ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1478ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1481ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
148797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
148897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
148997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
149097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
149197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
149397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
149497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
149597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
149697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
149797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
149897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
149997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
150097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
150297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
150397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
150497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
150597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
150697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
150797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
150897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
150997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
151097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
151297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
151397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
151497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
151697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
151797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
151897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
151997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
152097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
152197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
152297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
152397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
152497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1603729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1604729de186450f78c099637e1fce743fe531862c52Andreas Huber
16052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16322f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1633729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1634729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1635729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1636729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1640729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1641729de186450f78c099637e1fce743fe531862c52Andreas Huber
1642729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1643729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1644729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1645729de186450f78c099637e1fce743fe531862c52Andreas Huber
1646729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1649729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1650729de186450f78c099637e1fce743fe531862c52Andreas Huber
1651729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1656729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1657729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1658729de186450f78c099637e1fce743fe531862c52Andreas Huber
1659729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1660729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1661729de186450f78c099637e1fce743fe531862c52Andreas Huber
1662729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1663729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1664729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1665729de186450f78c099637e1fce743fe531862c52Andreas Huber
1666729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1667729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1668729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1669729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber
1673c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1674c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1676729de186450f78c099637e1fce743fe531862c52Andreas Huber
1677729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1678729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
176594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
176694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
198289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
198389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
198489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
198589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
198689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20240dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20250dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
204496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
204596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
204696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
204796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
204896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
204996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
205096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
205196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
205296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
206196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
214296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
220196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
221896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22717c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22727c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22737c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
231989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
232089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
232189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
232289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
232389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
232489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
232589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
232689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
232789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
232889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
235696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
236996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2448d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2449d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2450d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2451d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2452d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2453d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2454d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2455d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2456d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2457d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2458d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2459d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2460d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2461d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24627e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
24637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
24647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
24667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
24677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24717e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24727e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24767e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24797e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24807e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24817e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24827e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24837e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24847e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24857e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24867e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24877e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2495c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2496c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2497c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2498c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2502f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2519f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2524f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2539577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
254031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
254131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
254231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
254431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
254531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
254631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
254831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
254931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
255031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
255131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
255231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
255331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
255431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
255531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
255631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
255731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
256831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
256931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
257031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2604577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2605577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2606577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2607577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2608577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2609577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
261131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
261231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
261331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
261431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
261531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
261631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
261731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
261831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
261997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
263114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
263414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
263514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
263614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
263714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
263814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
263914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
264914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
265014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
265114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
265414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
265514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
265614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26618b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26638b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26649806555d3930be43e11106281dee354820ac1c88Andreas Huber
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26879806555d3930be43e11106281dee354820ac1c88Andreas Huber
2688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
272597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
272697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
272797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
272897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
272997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
273097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
273197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
273297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
273397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
273497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
273597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
273697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
273797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
273897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
273997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
274097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
274197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
274631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
274731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
274831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
274931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
275031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
275131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
275231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
275331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
275431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
275531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
275631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
275731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27585778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2759cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2760cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2761cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2763cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2764cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2765cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2777bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
279987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
280087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
280187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
280287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
280387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
280487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2824bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2825bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2826bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2827bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2828bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2829bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2861bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2862bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28651e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
28801e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2890bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2891bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2896bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2897bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2898bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2914eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2915eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2916496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2917496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2918496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2920496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2921496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2922496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2923496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2924496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2925496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2926496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2927496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2928496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2929496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2930496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2931496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2932496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2933496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2934eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2935eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2936eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2937eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2938eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2939eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2940eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2941eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2942eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2943eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2944eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2945eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2946eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2947eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2948eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2949eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2950eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2951eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2952eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2953eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2954f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2959f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
29837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
29847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
29857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
29867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
29877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2990ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2991ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2992ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2993ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2994ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2995ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2996ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
30210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
30220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
30230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
30240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
30250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
30260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
30270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
30280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
30290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
30300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
30803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
308629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3095349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3096349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3103d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3104d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3106d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3107d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
311296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
311396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
311496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3115d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3116d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3117d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3118d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3119d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3120d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31542d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31702d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3173a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
31745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31752d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3176a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31797fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
31807fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
31817fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
31827fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
31837fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
31847fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
31857fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
31867fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
31873831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3206dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3207dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3208dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3209dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3241078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3243078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3247078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3248d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3249d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3250d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3251d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3253078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3254d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3255078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3256349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3257d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3262d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3263d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3264054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3265054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3266054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3267054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3268054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3269054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3270054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3271054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3272054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3273054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3274054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3275054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3276054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3277054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3299dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
33003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3301dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3302dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3303dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
33043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3305dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3306dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3309349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3310349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3323dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3372349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3374d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3375d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3376d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3377d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3378d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3379d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3380d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3381d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3382d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3383d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3384d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3385d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3386d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3387d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3388d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3389d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3395054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
34085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
34105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
34115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
34125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
34155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
34165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
341731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3418577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3419577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3420577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
34214bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3422577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
34235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3425308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3427308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3428308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3429308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3430308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3431308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3432308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3433308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3434496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
343521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3436496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3437496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3438496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
344021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34428b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34502d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3466dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3496577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3497577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3498577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3499577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3500577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3501577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3502577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
35056aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
35066aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
35121e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3513cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3514cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
35155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3516cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3517cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3550c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3551349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3552c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3553c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3556c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3574f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3580ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3581ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3582ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3583ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3584ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3585ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3586ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3587ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3588ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3589ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3590ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3591308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3592ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
36115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3626c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3636c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3664ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3665ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3666ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3667ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3668ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3669ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3670ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3671ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3672ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3673e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3678d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3680e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3681e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3682e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3683afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3684e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3685e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3686e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3687afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3701e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37031065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37041065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
37051065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
37061065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37071065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
37081065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3709e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3710e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3712078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3713078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3714078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
37151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3716078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
37191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
37201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
37211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
37231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
37241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3725c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
37295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3732c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3733cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3735c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3737ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3741ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3742ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3743ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3744ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37450167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3746ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3747ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3748afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3771c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3772c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3773f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3774f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3775f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3776f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3777f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3780a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3791c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3799c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3800c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3802c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3803c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3807c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
38157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
38177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
38187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
38197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
38207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3839c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3842c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3843c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3854c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3870c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3871c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3872c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
38735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
38755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3878386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
38795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
38801173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
38811173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
38821173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
38831173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
38841ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
38851ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
38861ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
38871ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3896c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3897c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
39017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
39027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
39037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
39057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
39087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
39097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
39117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3912a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3913a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3914a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3915a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3916a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3917a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3918a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3919a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3920a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3921a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3922a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3923a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3924a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3925a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3926a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3927a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3928a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
392994ee4b708acfa941581160b267afb79192b1d816Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
393094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
393194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
393294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
393394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
393494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
393594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
393694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
393794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
393894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
393994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
394094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
394194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
394294ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
394394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
39447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
39457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
39467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
39477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
39487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
39497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
39507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
39517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
39527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
39537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
39547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
39557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
39567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
39577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3958c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
39595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
39605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
39625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
39753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3977cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3978cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
397929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3980cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3981cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3982cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
398491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
398591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3986cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
40136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
40146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
40166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
40196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
40206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
40226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
40236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
40256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
40623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4073d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4074d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4075d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4076d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4077d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4078d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4079d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4080d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4081d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4082d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4083d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4084d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4085d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4086d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4087d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4088d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
40896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4121f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4122349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4123349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4126f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4131054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4132054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4133054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4134054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4135054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4136054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4137054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4138054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4140054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4141054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
41424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
41434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
41444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4145054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4146054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4147054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4164349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4173c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4174054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4175054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4180349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
41813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4182349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4183349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4184349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4185349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4186349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4194349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4195349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
41993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4217349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4218349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42317a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4232d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4233d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4234d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4235d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4236d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4237d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4238d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4240349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4258496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4259496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4260496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4261496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4262496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4263496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4264496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4265496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4266496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4267496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4268496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4269a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4270a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4271a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4272a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4273a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4274a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4275a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4276a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4277a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4278a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4279a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4280a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4281a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4282a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4283a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4284a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4285a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
42877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
42886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
42907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
42917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
42927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
42934dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42944dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
42954dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
42964dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
42974dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
42984dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
42994dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
43004dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
43014dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
43024dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
43034dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
43044dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
43054dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4315a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4316530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4317a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4318a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4319a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4320a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4321a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4322a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4323a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4324a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4325a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4326a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4327a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4328a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4329a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4330a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4331a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4332a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4333a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4334a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4335a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4336e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4337e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4338e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4339e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4340b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4341b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4342e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4343e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4344e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4345e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4346b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4347b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4348b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4349b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4350b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4351b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4352b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4353b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4354b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4355b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4356b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4357b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4358b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4359b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4360b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4361b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4362e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4363e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4364a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4365a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4366a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43676507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
43686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
43696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
43706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
43716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
43726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
43736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
43746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
43756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
43766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
43776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4386054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4392349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
439531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
439631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
43983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4417f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4440349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4442349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
44433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4444349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4445349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
44603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4483cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4484cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
448529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4486cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4487cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4488cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
44895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4490d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4491755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4492755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4493755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4494755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4495755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4496755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4497755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4498755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4499cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
450631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4511349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4529f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
45305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
45315778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
45633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
456431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
456631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
45785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4584349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4585349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4586349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4587349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4588349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4590349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
45950af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
45975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46050167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
46060167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
46673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
46953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
47277a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4728d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4729d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4738e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4739e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4740e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4741e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4742e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4754349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4755349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4756349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4757349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4758349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4759349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4760349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4761349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4762349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
47633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4764349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4765349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4766349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4767349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4768349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4769349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4770349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
47947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
47957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
47967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
47977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4806dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4807f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4808f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4809f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4810f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4816