ACodec.cpp revision 87eb285dca94b20dc5f0ff8e60a0d395a4ca3be9
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
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        struct VideoDecoderOutputMetaData metaData;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        metaData.eType = kMetadataBufferTypeGrallocSource;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        metaData.pHandle = oldest->mGraphicBuffer->handle;
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        memcpy(oldest->mData->base(), &metaData, sizeof(metaData));
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p stored in %p)",
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                metaData.pHandle, oldest->mData->base());
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
864349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8692ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8702ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8712ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8722ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9302944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9312944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9322944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9332944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
940729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
941729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
942c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
943c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
944c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
945c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
95494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
95594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
956ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
957ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
960ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
961ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
9965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1035308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1036308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1038308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1039308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1040308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1069308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1070308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1071308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1072308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1073308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1074308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1092054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1093054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            // allow failure
1098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
111942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
112042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
112142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
112242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
112342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
112442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
112542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
112642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
112742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
112842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
112942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
113042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
113142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1138aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1142aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1143aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1144aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1145ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
11474471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
11484471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1150729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1152729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1154729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1155729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1156729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1157729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1158729de186450f78c099637e1fce743fe531862c52Andreas Huber
1159729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
11662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
11672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
11682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
11692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
11702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
11712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1174516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1175516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
11762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
11772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1178516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1180516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
11822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
11882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
11912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1192ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1193ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1194ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1195ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1196ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1197ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1198ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1199ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1200ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1202729de186450f78c099637e1fce743fe531862c52Andreas Huber
12034471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12109806555d3930be43e11106281dee354820ac1c88Andreas Huber
12118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12159806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12169806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12179806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12189806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12199806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12209806555d3930be43e11106281dee354820ac1c88Andreas Huber
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1295aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1296aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1361aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1387ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1388ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1390ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1391ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1443729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1444729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1446729de186450f78c099637e1fce743fe531862c52Andreas Huber
1447729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1448729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1449729de186450f78c099637e1fce743fe531862c52Andreas Huber
1450729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1451729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1452729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1453729de186450f78c099637e1fce743fe531862c52Andreas Huber
1454729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1459729de186450f78c099637e1fce743fe531862c52Andreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1463729de186450f78c099637e1fce743fe531862c52Andreas Huber
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1468729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1469729de186450f78c099637e1fce743fe531862c52Andreas Huber
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1473729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1474729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1475729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1476729de186450f78c099637e1fce743fe531862c52Andreas Huber
14772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
14782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
14792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
14812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
14822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
14832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
14842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
14862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
14892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
14902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
14912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
14922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
14952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
14962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
14972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
14982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1505729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1515729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1516729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber
1518729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber
1520729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1522729de186450f78c099637e1fce743fe531862c52Andreas Huber
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1524729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1525729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1530729de186450f78c099637e1fce743fe531862c52Andreas Huber
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1537729de186450f78c099637e1fce743fe531862c52Andreas Huber
1538729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1539729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1540729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1541729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1542729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber
1545c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1546c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1547729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1548729de186450f78c099637e1fce743fe531862c52Andreas Huber
1549729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1550729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1551729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1552729de186450f78c099637e1fce743fe531862c52Andreas Huber
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
163794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
163894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
18640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
18650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
18660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
18670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
18690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
18710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
18740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
18770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
18800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
18830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
18860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
18880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
18890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
18920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
18950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
18960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
18970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
18980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
18990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
191296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
191396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
191496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
191596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
191696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
191796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
191896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
191996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
192796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
192896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
200896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
200996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
208596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
20960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
20970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
20980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
20990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
21387c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
21397c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
21407c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
218296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
221296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
222596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2304d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2305d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2306d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2307d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2308d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2309d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2310d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2311d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2312d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2313d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2314d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2315d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2316d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2317d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23187e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
23267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
23277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
23307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23327e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
23337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
23347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
23357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
23387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
23397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
23407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
23417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
23437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
23447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
23457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
23477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
23507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
23517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2391577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
239231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
239331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
239431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
239531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
239631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
239731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
239831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
239931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
240031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
240131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
240231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
240431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
240631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
240731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
240831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
240931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
242031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
242131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
242231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2456577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2457577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2458577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2459577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2460577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2461577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2462e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
246331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
246431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
246531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
246631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
246731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
246831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
246931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
247031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2471e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2472e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
248314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
248614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
248714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
248814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
248914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
249014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
249114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
250114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
250214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
250314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
250614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
250714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
250814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25169806555d3930be43e11106281dee354820ac1c88Andreas Huber
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
25399806555d3930be43e11106281dee354820ac1c88Andreas Huber
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
258031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
258231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
258431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
258531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
258631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
258831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
259031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
259131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
25925778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2593cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2594cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2595cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2597cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2598cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2599cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
263387eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
263487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
263587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
263687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
263787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
263887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
263987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    }
264087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin
2641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
26701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
26711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
26991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27141e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2747eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2748eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2749eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2750496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2751496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2752496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2753496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2754496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2755496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2756496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2757496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2760496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2761496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2762496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2763496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2764496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2765496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2766496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2767496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2768eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2769eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2770eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2771eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2772eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2773eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2774eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2775eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2776eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2777eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2778eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2780eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2781eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2782eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2783eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2784eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2785eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2786eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2787eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2788f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2793f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
28227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
28237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2824ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2825ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2826ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2827ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2828ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2829ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2830ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
28550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
28560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
28570af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
28580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
28590af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
28600af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
28610af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
28620af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
28630af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
28640af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2922cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
29283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2930349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2938d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
294696fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
294796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
294896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
29882d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30042d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30082d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
30123831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
30133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
30142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
30205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
30215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
30225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
30235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3036dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3037dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3038dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3039dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
30585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
30595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
30605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
30723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3073078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
30745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
30755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
30765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3077078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
30823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3083078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3085078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3086349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3087d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3090d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3091d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3093d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
31205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
31225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
31265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3129dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
31303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3131dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3132dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3133dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
31343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3135dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3136dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31383856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3139349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3140349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3153dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32015778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3218d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3219d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3239349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
32405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
32415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
32465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
324731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3248577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3249577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3250577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3251e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3252577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3256308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3257308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3258308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3259308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3260308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3261308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3262308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3263308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3264496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
326521ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3266496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3267496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3268496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
327021ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32728b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
32738b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
32748b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
32795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
32802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
32925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
32935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3296dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3326577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3327577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3328577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3329577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3330577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3331577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3332577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
33356aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
33366aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
33405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
33421e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3343cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3344cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
33455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3346cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3347cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3378c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
33793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3380c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3381349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3382c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3383c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3385c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3386c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3404f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3409c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3410ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3411ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3412ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3413ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3414ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3415ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3416ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3417ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3418ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3419ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3420ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3421308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3422ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
34395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3450c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3456c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3466c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
34825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
34865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3494ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3495ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3496ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3497ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3498ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3499ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3500ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3501ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3502ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3503e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3508d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3510e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3511e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3512e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3514e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3515e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3516e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3517afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
35235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
35275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3531e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
35351065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
35361065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
35381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3539e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3540e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3542078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3543078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3544078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
35451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3546078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
35491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
35501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
35511065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35521065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
35531065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
35541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3555c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
35565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
35585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
35605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3562c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3563cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3564c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3565c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3571ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3572ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3573ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3574ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3575ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3576ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3577afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
35855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
35865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
35915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3594c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3595c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3596c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3598c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3602f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3603f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3604f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3605f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3606f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3607054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3608054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3609054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
36437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
36447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
36457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
36467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
36477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
36487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
36915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
36945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
36965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3698c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3699c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3700c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3706386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37081173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37091173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37101173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37111173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37121ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37131ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37141ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37151ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
37297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
37307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
37317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
37337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
37347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
37367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
37377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
37397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
37407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
37417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
37427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
37437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
37447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
37457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
37467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
37477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
37487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
37497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
37507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
37517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
37527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
37537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
37713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3773cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3774cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
377529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3776cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3777cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3778cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
378091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
378191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3782cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
38096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
38106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
38126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
38156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
38166463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38176463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
38186463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
38196463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
38206463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
38216463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38226463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38236463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3853f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
38583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3870d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3871d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3872d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3873d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3874d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3875d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3876d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3877d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3878d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3879d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3880d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3881d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3882d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3883d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3884d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
38856507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38866507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38876507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3918349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3922f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
3928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
3929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
3930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3933054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3934054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
3935054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
3936054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
3937054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3938054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3939054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3940054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3956349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3957349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3965054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
3966054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
3967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
3968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else {
3969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitRegularOutputBuffers();
3970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3974349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
39753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3976349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3977349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3978349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3979349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3980349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3988349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3989349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
39933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4004c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4005c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4008c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4009c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4010c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4011349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4012349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40257a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4026d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4027d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4028d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4029d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4030d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4031d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4032d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4033349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4034349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4053496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4055496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4056496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4057496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4058496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4059496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4060496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4061496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4062496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4063a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4064a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4065a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4066a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4067a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4068a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4069a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4070a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4071a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4072a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4073a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4074a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4075a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4076a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4077a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4078a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4079a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
40807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
40817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
40826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
40847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
40857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
40867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4095a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4096a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4097a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
4098a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4099a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4100a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4101a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4102a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4103a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4104a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4105a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4106a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4107a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4108a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4109a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4110a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4111a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4112a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4113a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4114a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4115a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4116a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4117a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4118a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4119a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41206507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
41216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
41226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
41236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
41246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
41256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
41266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
41276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
41286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
41296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
41306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4139054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4145349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
414831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
414931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
41513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4170f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4193349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4195349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
41963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4197349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
42133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4236cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4237cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
423829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4239cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4240cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4241cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
42425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4243d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4244755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4245755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4246755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4247755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4248755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4249755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4250755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4251755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4252cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
425831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
425931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4282f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
42835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
42845778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
43163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
431731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
431931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
43315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4337349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4338349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4339349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4340349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4341349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4342349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4343349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
43480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4358bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4359bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4360bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4361bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4362bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4386f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
44193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4442f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
44473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
44797a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4480d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4481d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4490e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4491e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4492e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4493e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4494e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4506349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4507349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4508349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4509349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4510349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4511349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4514349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4516349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4518349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4519349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4520349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4521349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4522349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
45467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
45477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
45487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
45497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4558dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4559f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4560f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4561f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4562f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4568