ACodec.cpp revision d0715867861c216e88a4a7523b6da8a3cb128724
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),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mMetaDataBuffersToSubmit(0) {
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
387dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4175778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4315778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4367a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
462054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
496308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
505308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
533eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
537eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
539eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
56929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5753c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6083c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
615054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
616258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
651054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6698ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
67774006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
67874006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68074006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68274006804065941841883c4b46ee785070164023fJamie Gennis
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
68874006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69374006804065941841883c4b46ee785070164023fJamie Gennis
6943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70674006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
708054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7871e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7978ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7981e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
802c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
837d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
838d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
840d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
842d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
848d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
850054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8742ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8752ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
905f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9352944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
945729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
946729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
947c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
948c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
949c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
95994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
961ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
962ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
965ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
966ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10015ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10272f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1040308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1041308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1042d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1043308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1045308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1046d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1047308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1074308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            // allow failure
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1112308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
112442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
112542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
112642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
112742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
112842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
112942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
113042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
113142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
113242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
113342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
113442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
113542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
113642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1143aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1144ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1145ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1147aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1148aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1149aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1150ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1151ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
11524471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
11534471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1155729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1157729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1159729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1160729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1161729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1162729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1163729de186450f78c099637e1fce743fe531862c52Andreas Huber
1164729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
11712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
11742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
11752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
11762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
11772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
11782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1180516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
11812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
11822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1188516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
11922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
11932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1194516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1195516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
11962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1197ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1198ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1199ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1200ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1201ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1202ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1203ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1204ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1205ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1207729de186450f78c099637e1fce743fe531862c52Andreas Huber
12084471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12094471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12104471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12114471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12159806555d3930be43e11106281dee354820ac1c88Andreas Huber
12168b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12178b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12209806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12219806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12229806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12239806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12249806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12259806555d3930be43e11106281dee354820ac1c88Andreas Huber
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1300aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1301aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1302ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1305ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1366aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1392ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1393ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1394ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1395ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1448729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1449729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1451729de186450f78c099637e1fce743fe531862c52Andreas Huber
1452729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1453729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1454729de186450f78c099637e1fce743fe531862c52Andreas Huber
1455729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1456729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1457729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1458729de186450f78c099637e1fce743fe531862c52Andreas Huber
1459729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1464729de186450f78c099637e1fce743fe531862c52Andreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1468729de186450f78c099637e1fce743fe531862c52Andreas Huber
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1473729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1474729de186450f78c099637e1fce743fe531862c52Andreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1478729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1479729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1480729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1481729de186450f78c099637e1fce743fe531862c52Andreas Huber
14822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
14832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
14842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
14862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
14872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
14882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
14892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
14912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
14942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
14952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
14962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
14972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1510729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1515729de186450f78c099637e1fce743fe531862c52Andreas Huber
1516729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1518729de186450f78c099637e1fce743fe531862c52Andreas Huber
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1520729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1522729de186450f78c099637e1fce743fe531862c52Andreas Huber
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1524729de186450f78c099637e1fce743fe531862c52Andreas Huber
1525729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1530729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1537729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1538729de186450f78c099637e1fce743fe531862c52Andreas Huber
1539729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1540729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1541729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1542729de186450f78c099637e1fce743fe531862c52Andreas Huber
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1545729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1546729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1547729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1548729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1549729de186450f78c099637e1fce743fe531862c52Andreas Huber
1550c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1551c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1552729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1553729de186450f78c099637e1fce743fe531862c52Andreas Huber
1554729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1555729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1556729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1557729de186450f78c099637e1fce743fe531862c52Andreas Huber
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
164294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
164394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
18690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
18700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
18710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
18720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
18740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
18760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
18790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
18820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
18850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
18880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
18910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
18930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
18940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
18970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
191796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
191896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
191996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
192096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
192196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
192296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
192396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
192496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
193296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
193396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
201396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
201496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
207396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
209096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
21437c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
21447c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
21457c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
218796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
221796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2309d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2310d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2311d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2312d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2313d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2314d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2315d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2316d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2317d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2318d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2319d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2320d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2321d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2322d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23237e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
23317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
23327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
23357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23377e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
23387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
23397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
23407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
23437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
23447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
23457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
23467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
23487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
23497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
23507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
23527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
23557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
23567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2396577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
239731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
239831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
239931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
240131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
240231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
240331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
240531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
240631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
240731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
240931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
241031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
241131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
241231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
241331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
241431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
242531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
242631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
242731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2458e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2459e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2460e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2461577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2462577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2463577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2464577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2465577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2466577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2467e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
246831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
246931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
247031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
247131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
247231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
247331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
247431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
247531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2483e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2486e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
248814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
249114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
249214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
249314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
249414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
249514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
249614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
250614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
250714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
250814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
251114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
251214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
251314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25219806555d3930be43e11106281dee354820ac1c88Andreas Huber
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
25449806555d3930be43e11106281dee354820ac1c88Andreas Huber
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
258531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
258631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
258731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
258931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
259031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
259131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
259231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
259331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
259431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
259531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
259631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
25975778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2598cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2599cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2600cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2602cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2603cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2604cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
263887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
263987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
264087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
264187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
264287eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
264387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
26751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
26761e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27041e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27191e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2752eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2753eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2754eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2755496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2756496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2757496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2761496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2762496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2763496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2764496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2765496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2766496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2767496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2768496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2769496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2770496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2771496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2772496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2773eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2774eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2775eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2776eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2777eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2778eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2780eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2781eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2782eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2783eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2784eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2785eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2786eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2787eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2788eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2789eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2790eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2791eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2792eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2793f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2798f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
28277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
28287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2829ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2830ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2831ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2832ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2833ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2834ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2835ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
28600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
28610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
28620af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
28630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
28640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
28650af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
28660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
28670af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
28680af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
28690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2927cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
29333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2934349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2935349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2947d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
295196fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
295296fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
295396fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2955d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2956d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2957d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2958d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
29932d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30092d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
30173831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
30183831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
30192d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
30255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
30265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3041dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3042dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3043dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3044dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
30635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
30645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
30655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3067d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3068d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3069d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3076078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
30773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3078078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3082078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
30873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3088078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3090078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3091349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3094d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3095d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3096d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3097d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3098d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
31285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
31325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3134dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
31353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3136dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3137dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3138dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
31393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3140dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3141dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3144349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3145349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3158dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32065778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3207349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3220d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3230054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
32435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
32475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
32505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
32515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
325231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3253577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3254577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3255577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3256e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3257577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3260308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3261308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3262308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3263308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3264308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3265308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3266308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3268308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3269496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
327021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3271496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3272496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3273496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
327521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
32788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
32798b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
32852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3301dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3331577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3332577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3333577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3334577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3335577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3336577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3337577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
33406aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
33416aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
33471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3348cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3349cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3351cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3352cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
33843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3385c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3386349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3387c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3388c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3390c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3391c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3409f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3415ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3416ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3417ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3418ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3419ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3420ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3421ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3422ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3423ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3424ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3425ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3426308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3427ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
34445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
34455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
34465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
34475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3461c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3471c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
34875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
34905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
34915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
34935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3499ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3500ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3501ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3502ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3503ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3504ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3505ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3506ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3507ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3508e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3513d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3515e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3516e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3517e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3518afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3519e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3520e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3521e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3522afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3536e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
35401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
35411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
35431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3544e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3545e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3547078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3548078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3549078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
35501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3551078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
35541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
35551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
35561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
35581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
35591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3560c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3567c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3568cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3569c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3570c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3572ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3577ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3578ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3579ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3580ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3581ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3582afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
35875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
35885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
35895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
35905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
35965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3598c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3602c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3607f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3608f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3609f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3610f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3611f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3612054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3613054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3614054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3647c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
36487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
36497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
36507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
36517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
36527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
36537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
36985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3703c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3704c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3705c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3711386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37131173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37141173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37151173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37161173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37171ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37181ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37191ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37201ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3729c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3730c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
37347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
37357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
37367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
37387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
37397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
37417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
37427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
37447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
37457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
37467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
37477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
37487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
37497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
37507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
37517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
37527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
37537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
37547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
37557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
37567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
37577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
37587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3759c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
37605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
37635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3771f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
37763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3779cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
378029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3781cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3782cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3783cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
37845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
378591bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
378691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3787cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38136507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
38146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
38156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
38176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
38206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
38216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
38236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
38246463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
38256463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
38266463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38276463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38286463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3858f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
38633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3875d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3876d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3877d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3878d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3879d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3880d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3881d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3882d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3883d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3884d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3885d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3886d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3887d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3888d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3889d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
38906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3922f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3923349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3927f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
3933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
3934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
3935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
3940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
3941054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
3942054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3943054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3944054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3945054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3961349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3962349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
3971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
3972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
3973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else {
3974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitRegularOutputBuffers();
3975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3979349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
39803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3981349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3982349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3983349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3984349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3985349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3993349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3994349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
39983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4011c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4012c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4013c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4014c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4015c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40307a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4031d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4032d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4033d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4034d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4035d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4036d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4037d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4038349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4039349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4057496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4058496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4059496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4060496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4061496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4062496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4063496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4064496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4065496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4066496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4067496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4068a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4069a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4070a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4071a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4072a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4073a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4074a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4075a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4076a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4077a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4078a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4079a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4082a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
40857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
40867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
40876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
40897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
40907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
40917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4100a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4101a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4102a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
4103a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4104a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4105a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4106a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4107a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4108a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4109a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4110a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4111a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4112a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4113a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4114a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4115a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4116a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4117a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4118a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4119a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4120a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4121a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4122e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4123e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4124e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4125e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4126e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        CHECK_EQ((status_t)OK,
4127e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                 mOMX->setInternalOption(
4128e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4129e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4130e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4131e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4132e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     sizeof(suspend)));
4133e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4134e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4137a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41386507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
41396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
41406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
41416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
41426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
41436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
41446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
41456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
41466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
41476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
41486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
415631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
416631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
416731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
41693856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4211349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4213349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
42143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4215349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4216349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
42313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4254cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4255cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
425629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4257cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4258cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4259cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
42605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4261d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4262755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4263755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4264755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4265755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4266755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4267755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4268755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4269755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4270cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
427631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
427731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4283349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4284349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4300f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
43015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
43025778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
43343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
433531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
433731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
43495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4356349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4357349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4358349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4359349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4360349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4361349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
43660af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
43685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4376bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4377bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4378bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4379bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4380bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4381bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4382bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4383bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
44373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4460f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
44653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
44977a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4498d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4499d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4508e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4509e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4510e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4511e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4512e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4528349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4529349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4530349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4531349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4532349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4534349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4535349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4536349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4537349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4538349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4539349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4540349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
45647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
45657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
45667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
45677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4575dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4576dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4577f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4578f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4579f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4580f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4586