ACodec.cpp revision 79ee2399b67c7a11042c5904dc1309712a76f8cb
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
388dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4377a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
498308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6093c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
67874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
67974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68374006804065941841883c4b46ee785070164023fJamie Gennis
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
68974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69474006804065941841883c4b46ee785070164023fJamie Gennis
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
797f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7988ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
837d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
838d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
842d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
850d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8752ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
946729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
947729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
948c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
949c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
962ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
963ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
966ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
967ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1041308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1045308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1111fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1112fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1113fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1114fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1115fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1116fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1117fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1118fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1119fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1120fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1121fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1122fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1123fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1124fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1125fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1126fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1127fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1128fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1129fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1130fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1131fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1132fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1133fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1134fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1135fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1136fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1137fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1138fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1139fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1140fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1141fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
1142fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
1143fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1144fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1145fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1146fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1147fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1148fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1149fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1150fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1151fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1152054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1153054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1154054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1155054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1156054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11570167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11580167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11590167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11600167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11610167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11620167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1165308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
117742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
117842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
117942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
118042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
118142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
118242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
118342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
118442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
118542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
118642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
118742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
118842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
118942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1196aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1197ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1198ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1200aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1201aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1202aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1203ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1204ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1208729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1210729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1212729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1213729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1214729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1215729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1216729de186450f78c099637e1fce743fe531862c52Andreas Huber
1217729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12252f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12262f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12312f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1232516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1233516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1236516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1237516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1238516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1241516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1242516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1243516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1247516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1248516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1250ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1251ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1252ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1253ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1254ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1255ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1256ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1257ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1258ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1260729de186450f78c099637e1fce743fe531862c52Andreas Huber
12614471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12624471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12634471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12644471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12678b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12689806555d3930be43e11106281dee354820ac1c88Andreas Huber
12698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12718b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12739806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12749806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12759806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12769806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12779806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12789806555d3930be43e11106281dee354820ac1c88Andreas Huber
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1353aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1354aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1355ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1356ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1358ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1419aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1445ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1446ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1447ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1448ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1449ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1501729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1502729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1504729de186450f78c099637e1fce743fe531862c52Andreas Huber
1505729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber
15352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
15362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
15372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
15392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1563729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1564729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1565729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1568729de186450f78c099637e1fce743fe531862c52Andreas Huber
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1571729de186450f78c099637e1fce743fe531862c52Andreas Huber
1572729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1573729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1574729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1575729de186450f78c099637e1fce743fe531862c52Andreas Huber
1576729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1577729de186450f78c099637e1fce743fe531862c52Andreas Huber
1578729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1579729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1580729de186450f78c099637e1fce743fe531862c52Andreas Huber
1581729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1582729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1583729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1584729de186450f78c099637e1fce743fe531862c52Andreas Huber
1585729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1586729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1587729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1588729de186450f78c099637e1fce743fe531862c52Andreas Huber
1589729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1590729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1591729de186450f78c099637e1fce743fe531862c52Andreas Huber
1592729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1593729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1594729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1595729de186450f78c099637e1fce743fe531862c52Andreas Huber
1596729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1597729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1598729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1599729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1600729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1601729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1602729de186450f78c099637e1fce743fe531862c52Andreas Huber
1603c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1604c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1605729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1606729de186450f78c099637e1fce743fe531862c52Andreas Huber
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1609729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1670f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1689e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
169594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
169694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
191389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
191489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
191589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
191689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19260dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
19270dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
19280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
19290dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
19300dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19310dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
19320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
19340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
19370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
19400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
19430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
19440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
197496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
197596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
197696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
197796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
197896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
197996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
198096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
198196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
198296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
199196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
207196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
207296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
213196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
214896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
22017c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
22027c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
22037c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
224989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
225089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
225189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
225289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
225389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
225489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
225589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
225689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
225789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
225889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
228596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
228696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
229996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2378d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2379d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2380d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2381d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2382d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2383d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2384d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2385d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2386d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2387d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2388d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2389d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2390d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2391d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23927e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
24007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
24017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
24047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24067e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
24077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
24087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
24097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
24127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
24137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
24147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
24157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
24177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
24187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
24197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
24217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
24237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
24247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2425c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2426c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2427c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2428c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
24297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
24307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
24317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2432f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
24393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2469577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
247031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
247131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
247231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
247331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
247431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
247531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
247631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
247731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
247831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
247931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
248031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
248231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
248431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
248531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
248631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
248731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2488e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
249831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
249931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
250031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2534577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2535577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2536577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2537577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2538577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2539577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
254131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
254231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
254331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
254431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
254531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
254631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
254731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
254831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
256114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
256414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
256514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
256614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
256714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
256814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
256914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
257914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
258014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
258114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
258414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
258514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
258614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25918b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25949806555d3930be43e11106281dee354820ac1c88Andreas Huber
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
26179806555d3930be43e11106281dee354820ac1c88Andreas Huber
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
265831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
265931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
266031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
266231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
266331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
266431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
266631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
266731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
266831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
266931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2671cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2672cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2673cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2675cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2676cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2677cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
271187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
271287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
271387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
271487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
271587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
271687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
27481e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
27491e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2767bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2768bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2769bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27771e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2778bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2779bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2780bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2781bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2782bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2783bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2784bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2785bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2786bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2787bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2788bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2789bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2790bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2825eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2826eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2827eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2828496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2829496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2830496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2831496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2832496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2833496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2834496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2835496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2836496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2837496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2838496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2839496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2840496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2841496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2842496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2843496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2844496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2845496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2846eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2847eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2848eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2849eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2850eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2851eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2852eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2853eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2854eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2855eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2856eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2857eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2858eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2859eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2860eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2861eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2862eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2863eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2864eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2865eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2866f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2871f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
29007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
29017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2902ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2903ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2904ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2905ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2906ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2907ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2908ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
29330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
29340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
29350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
29360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
29370af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
29380af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
29390af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
29400af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
29410af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
29420af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
299829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3000cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
30063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3007349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3008349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3015d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3016d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3017d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3018d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3019d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3020d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3021d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3022d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3023d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
302496fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
302596fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
302696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3027d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30662d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30822d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3085a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30872d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3088a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
30927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
30937fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
30947fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
30957fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
30967fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
30977fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
30987fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
30993831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
31002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
31045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
31055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
31065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
31075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
31085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3118dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3119dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3120dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3121dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3147d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
31543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3155078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
31565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
31575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
31585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3159078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3160d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3161d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3162d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3163d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3165078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3166d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3167078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3168349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3169d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3170d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3171d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3172d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3173d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3174d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3175d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3176054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3177054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3178054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3179054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3180054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3181054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3182054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3183054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3184054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3185054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3186054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3187054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3188054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3189054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
32025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
32035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
32045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
32085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
32095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3211dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
32123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3213dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3214dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3215dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
32163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3217dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3218dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3221349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3222349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3235dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3290d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3291d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3292d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3293d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3294d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3295d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3296d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3297d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3298d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3299d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3300d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3301d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3307054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
33195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
33245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
33275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
332931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3330577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3331577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3332577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3334577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3337308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3338308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3339308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3340308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3341308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3342308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3343308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3344308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3345308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3346496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
334721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3349496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
335221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33548b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
33558b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
33568b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
33575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33622d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3378dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3408577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3409577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3410577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3411577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3412577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3413577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3414577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
34176aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
341879ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
34225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
34241e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3425cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3426cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3428cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3429cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3460c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3462c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3463349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3464c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3465c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3467c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3468c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3492ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3493ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3494ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3495ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3496ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3497ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3498ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3499ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3500ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3501ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3502ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3503308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3504ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3538c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3548c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3560c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3562c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3563c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3566c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3576ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3577ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3578ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3579ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3580ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3581ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3582ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3583ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3584ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3585e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3590d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3592e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3593e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3594e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3595afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3596e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3597e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3598e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3599afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
36025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
36095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
36105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
36115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
36125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3613e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36161065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
36171065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
36181065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
36201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3621e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3622e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3624078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3625078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3626078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
36271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3628078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
36311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
36321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
36331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
36341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
36351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
36361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3637c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
36405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
36415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
36425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
36435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3644c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3645cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3647c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3649ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3653ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3654ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3655ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3656ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
36570167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3658ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3659ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3660afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
36745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3685f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3686f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3687f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3688f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3689f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3692a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3693054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3695c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3710c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3711c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3712c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3718c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3719c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3720c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3721c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
37277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
37287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
37297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
37307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
37317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
37327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
37337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3734c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3735c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3736c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3737c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3739c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3740c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3742c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3744c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3745c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3749c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3750c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3751c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3752c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3753c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3761c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3762c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3764c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3765c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3770c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
37725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
37735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
37755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
37775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3782c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3783c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3784c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3790386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37921173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37951173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37961ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37971ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37981ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37991ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3808c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
38137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
38147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
38157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
38177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
38187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
38207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
38217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
38227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
38237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3824a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3825a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3826a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3827a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3828a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3829a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3830a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3831a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3832a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3833a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3834a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3835a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3836a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3837a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3838a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3839a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3840a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
38417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
38427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
38437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
38447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
38457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
38467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
38477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
38487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
38497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
38507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
38517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
38527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
38537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
38547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
38565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
38575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3867f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
38723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3875cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
387629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3877cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3878cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3879cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
388191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
388291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3883cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
39116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
39136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
39166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
39176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
39186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
39196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
39206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
39216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
39226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
39236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
39246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3954f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
39593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3971d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3972d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3973d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3974d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3975d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3976d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3977d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3978d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3979d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3980d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3981d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3982d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3983d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3984d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3985d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
39866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4020349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4028054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4029054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4030054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4031054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4032054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4033054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4034054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4035054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4036054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4037054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4038054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4039054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4040054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4041054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4057349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4058349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4066054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4067c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4068054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4069054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4070054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4071054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4072054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4073f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4074349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
40753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4076349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4077349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4078349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4079349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4080349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4088349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4089349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
40933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4104c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4105c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4110c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4111349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4112349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
41257a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4126d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4127d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4128d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4129d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4130d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4131d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4132d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4133349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4134349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4152496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4153496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4154496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4155496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4157496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4163a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4164a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4165a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4166a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4167a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4168a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4169a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4170a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4171a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4173a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4174a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4175a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4176a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4177a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4178a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4179a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
41826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
41847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
41857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4197530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4199a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4203a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4204a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4205a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4206a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4207a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4208a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4209a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4210a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4211a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4212a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4213a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4214a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4215a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4216a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4217e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4218e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4219e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4220e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4221b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4222b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4223e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4224e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4225e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4226e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4227b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4228b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4229b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4230b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4231b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4232b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4233b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4234b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4235b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4236b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4237b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4238b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4239b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4240b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4241b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4242b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4243e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4244e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4245a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4246a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4247a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
42486507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
42496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
42506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
42516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
42526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
42536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
42546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
42556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
42566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
42576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
42586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4267054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
427631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
427731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
42793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4321349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4323349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
43243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4325349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4326349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
43413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4364cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4365cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
436629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4367cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4368cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4369cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
43705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4371d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4372755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4373755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4374755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4375755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4376755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4377755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4378755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4379755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4380cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
438631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
438731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4392349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4393349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4394349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
44115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
44125778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
44443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
444531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
44465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
444731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
44595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4465349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4466349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4467349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4468349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4469349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4470349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4471349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
44760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
44785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44860167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
44870167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4488bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4489bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4490bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4491bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4492bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4493bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4494bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4515f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
45483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4571f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
45763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
46087a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4609d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4610d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4619e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4620e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4621e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4622e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4623e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4636349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4637349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4638349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4639349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4640349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4641349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4642349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4643349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
46443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4645349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4646349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4647349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4648349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4649349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4650349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4651349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
46757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
46767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
46777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
46787e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4686dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4687dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4688f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4689f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4690f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4691f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4697