ACodec.cpp revision a73c954d947748a3b6f630cf2c160fe55ec596e3
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
372a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
373a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mRepeatFrameDelayUs(-1ll) {
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
375c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
388dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4325778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
436f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4377a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
441f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
467054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
495afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
498308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
509308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5201065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5231065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
536eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
538eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
540eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
543eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
551054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
57029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5783c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5833c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6093c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
616054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
619054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
631054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
663054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
666054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
669054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6708ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6711e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
67874006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
67974006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
680054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68174006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68374006804065941841883c4b46ee785070164023fJamie Gennis
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
68974006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69374006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69474006804065941841883c4b46ee785070164023fJamie Gennis
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70774006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
711054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
797f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7988ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7991e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8011e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
804c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
837d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
838d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
839d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
841d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
842d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
843d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
844d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
845d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
846d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
849d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
850d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
851054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
852054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
870349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8752ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8762ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8772ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8782ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9362944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9372944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9382944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9392944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
946729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
947729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
948c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
949c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
950c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
951c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
96094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
96194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
962ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
963ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
966ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
967ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10282f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10292f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10302f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1035d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1036d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1038d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1039d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1040d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1041308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1043d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1044308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1045308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1046308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1047d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1048308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10693a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10703a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10713a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10723a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10733a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10743a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1092308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1093a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1094a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1095a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1096a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1097a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1098a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
1099308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1100308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1107054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1108054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1109054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            // allow failure
1110054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1111054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1112054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1113054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1114054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
11170167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
11180167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
11190167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
11200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
11210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
11220167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1125308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
113742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
113842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
113942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
114042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
114142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
114242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
114342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
114442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
114542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
114642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
114742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
114842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
114942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1156aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1158ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1159ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1160aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1161aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1162aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1163ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
11654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
11664471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1168729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1170729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1172729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1173729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1174729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1175729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1176729de186450f78c099637e1fce743fe531862c52Andreas Huber
1177729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
11842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
11852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
11862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
11882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
11892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
11902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
11912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1192516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1193516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
11942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
11952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1196516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1197516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1198516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1201516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1202516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1203516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
12052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
12062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1207516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1208516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
12092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1210ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1211ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1212ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1213ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1214ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1215ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1216ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1217ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1218ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1220729de186450f78c099637e1fce743fe531862c52Andreas Huber
12214471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12224471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12234471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12244471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12258b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12268b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12278b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12289806555d3930be43e11106281dee354820ac1c88Andreas Huber
12298b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12308b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12318b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12328b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12339806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12349806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12359806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12369806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12379806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12389806555d3930be43e11106281dee354820ac1c88Andreas Huber
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1313aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1314aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1315ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1316ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1317ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1318ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1379aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1405ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1406ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1407ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1408ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1409ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1461729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1462729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1464729de186450f78c099637e1fce743fe531862c52Andreas Huber
1465729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1466729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1467729de186450f78c099637e1fce743fe531862c52Andreas Huber
1468729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1469729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1470729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1471729de186450f78c099637e1fce743fe531862c52Andreas Huber
1472729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1477729de186450f78c099637e1fce743fe531862c52Andreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1481729de186450f78c099637e1fce743fe531862c52Andreas Huber
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1486729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1487729de186450f78c099637e1fce743fe531862c52Andreas Huber
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1491729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1492729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1493729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1494729de186450f78c099637e1fce743fe531862c52Andreas Huber
14952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
14962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
14972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
14992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
15012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
15022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
15042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15062f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
15072f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
15102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
15112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
15122f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
15132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
15142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
15152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
15162f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
15172f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15192f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15202f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15212f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1523729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1524729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1525729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1530729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1537729de186450f78c099637e1fce743fe531862c52Andreas Huber
1538729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1539729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1540729de186450f78c099637e1fce743fe531862c52Andreas Huber
1541729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1542729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber
1545729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1546729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1547729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1548729de186450f78c099637e1fce743fe531862c52Andreas Huber
1549729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1550729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1551729de186450f78c099637e1fce743fe531862c52Andreas Huber
1552729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1553729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1554729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1555729de186450f78c099637e1fce743fe531862c52Andreas Huber
1556729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1557729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1558729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1559729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1560729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1561729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1562729de186450f78c099637e1fce743fe531862c52Andreas Huber
1563c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1564c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1565729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1566729de186450f78c099637e1fce743fe531862c52Andreas Huber
1567729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1568729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1569729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1570729de186450f78c099637e1fce743fe531862c52Andreas Huber
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1630f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
165594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
165694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1674e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1675e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1686e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1688e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
18820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
18830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
18840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
18850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
18870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
18890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
18920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
18950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
18980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
19000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
19010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
19040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
19060dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
19070dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
19080dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19090dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
19100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19110dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19120dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
19130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
19140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
19150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
19160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
19170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
192996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
193096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
193196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
193296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
193396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
193496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
193596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
193696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
193796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
194596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
194696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
201096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
202696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
202796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
210296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
210396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21130dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
21140dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
21150dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
21160dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
21170dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21180dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21190dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21200dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21210dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21220dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21230dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21280dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
21567c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
21577c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
21587c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
220096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
222996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
223096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
224396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2313f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2322d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2323d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2324d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2325d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2326d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2327d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2328d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2329d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2330d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2331d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2332d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2333d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2334d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2335d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23367e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
23447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
23457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
23487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23507e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
23517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
23527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
23537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23557e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
23567e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
23577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
23587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
23597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
23617e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
23627e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
23637e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23647e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
23657e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23667e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
23687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2369c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2370c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2371c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2372c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
23737e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2393f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2398f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2403f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2413577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
241431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
241531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
241631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
241731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
241831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
241931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
242031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
242131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
242231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
242331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
242431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
242531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
242631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
242731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
242831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
242931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
243031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
243131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
244231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
244331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
244431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2458e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2459e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2460e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2461e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2462e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2463e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2465e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2466e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2467e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2468e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2469e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2470e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2471e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2472e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2478577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2479577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2480577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2481577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2482577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2483577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
248531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
248631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
248731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
248831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
248931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
249031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
249131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
249231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
250514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2506e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2507e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
250814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
250914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
251014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
251114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
251214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
251314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
252314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
252414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
252514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
252814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
252914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
253014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25389806555d3930be43e11106281dee354820ac1c88Andreas Huber
2539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
25619806555d3930be43e11106281dee354820ac1c88Andreas Huber
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
260231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
260331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
260431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
260531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
260631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
260731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
260831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
260931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
261031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
261131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
261231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
261331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
26145778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2615cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2616cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2617cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
26185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2619cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2620cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2621cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
265587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
265687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
265787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
265887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
265987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
266087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2662bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2663bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
26921e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
26931e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2706bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
27211e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27361e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2737bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2738bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2739bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2740bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2741bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2742bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2743bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2744bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2745bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2746bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2747bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2748bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2749bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2750bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2751bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2752bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2753bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2754bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2755bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2756bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2757bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2758bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2759bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2760bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2761bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2762bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2763bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2764bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2765bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2766bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2769eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2770eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2771eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2772496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2773496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2774496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2775496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2776496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2777496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2778496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2779496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2780496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2781496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2782496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2783496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2784496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2785496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2786496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2787496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2788496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2789496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2790eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2791eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2792eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2793eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2794eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2795eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2796eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2797eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2798eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2799eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2800eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2801eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2802eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2803eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2804eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2805eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2806eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2807eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2808eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2809eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2810f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2815f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
28447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
28457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2846ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2847ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2848ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2849ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2850ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2851ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2852ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28760af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
28770af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
28780af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
28790af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
28800af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
28810af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
28820af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
28830af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
28840af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
28850af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
28860af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2933f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2944cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
29503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2951349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2952349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2959d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2960d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2961d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2962d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2963d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2964d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2965d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2966d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2967d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
296896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
296996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
297096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2971d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2972d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2973d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2974d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2975d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2976d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
30102d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
30285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3029a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
30305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30312d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3032a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
30363831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
30373831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
30382d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3039a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        mode = KEEP_BUFFERS;
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
30435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
30445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
30455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
30465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3057dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3058dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3059dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3060dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
30795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
30805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
30815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3086d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3092078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
30933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3094078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
30955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
30965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
30975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3098078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3099d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3100d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3101d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3102d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
31033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3104078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3105d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3106078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3107349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3108d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3109d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3110d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3111d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3112d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3113d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3114d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3115054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3116054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3117054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3118054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3119054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3120054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3121054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3122054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3123054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3124054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3125054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3126054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3127054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3128054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
31415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
31425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
31435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
31445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
31455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
31475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
31485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3150dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
31513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3152dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3153dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3154dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
31553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3156dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3157dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3160349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3174dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3223349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3227d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3228d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3229d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3230d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3231d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3232d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3233d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3234d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3235d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3236d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3237d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3238d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3239d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3240d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3246054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
32585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
32595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3260349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
32615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
32625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
32635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
32665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
32675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
326831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3269577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3270577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3271577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3272e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3273577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
32745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3276308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3277308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3278308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3279308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3280308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3281308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3282308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3283308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3284308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3285496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
328621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3287496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3288496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3289496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
32905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
329121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32938b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
32948b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
32958b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
32965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
33012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
33095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
33135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
33145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3317dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3347577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3348577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3349577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3350577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3351577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3352577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3353577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
33566aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
33576aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
33615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
33631e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3364cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3365cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3367cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3368cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3399c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
34003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3401c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3402349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3403c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3404c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3406c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3407c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3425f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3430c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3431ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3432ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3433ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3434ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3435ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3436ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3437ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3438ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3439ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3440ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3441ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3442308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3443ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
34595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
34605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
34615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
34625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
34635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3467c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3477c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3487c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
35035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
35065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
35075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
35095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3515ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3516ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3517ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3518ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3519ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3520ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3521ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3522ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3523ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3524e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
35255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3529d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3531e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3532e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3533e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3534afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3535e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3536e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3537e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3538afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
35435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3552e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35541065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35551065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
35561065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
35571065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35581065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
35591065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3560e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3561e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3563078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3564078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3565078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
35661065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3567078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35691065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
35701065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
35711065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
35721065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35731065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
35741065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
35751065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3576c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
35795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
35805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
35815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
35825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3583c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3584cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3586c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3588ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3592ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3593ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3594ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3595ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
35960167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3597ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3598ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3599afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
36045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
36055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
36065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
36075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
36085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
36135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3624f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3625f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3626f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3627f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3628f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3631a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3632054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3635c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3636c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3637c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3638c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3639c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3640c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3641c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3647c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
36667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
36677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
36687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
36697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
36707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
36717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3679c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3681c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3686c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3689c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3690c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3691c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3692c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3695c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3701c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3706c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3708c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3709c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
37105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3721c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3722c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3723c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3729386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
37305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37311173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37331173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37351ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37361ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37371ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37381ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
37455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3748c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
37527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
37537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
37547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
37567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
37577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
37597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
37607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
37627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3763a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3764a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3765a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3766a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3767a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3768a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3769a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3770a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3771a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3772a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3773a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3774a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3775a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3776a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3777a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3778a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3779a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
37807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
37817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
37827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
37837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
37847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
37857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
37867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
37877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
37887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
37897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
37907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
37917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
37927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
37937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3806f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3810f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
38113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3813cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3814cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
381529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3816cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3817cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3818cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
38195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
382091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
382191bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3822cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
38496463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
38506463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38516463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
38526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
38556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
38566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
38586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
38596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
38606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
38616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3893f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
38983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3909d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3910d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3911d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3912d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3913d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3914d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3915d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3916d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3917d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3918d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3919d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3920d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3921d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3922d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3923d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3924d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
39256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
39266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
39276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
39296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
39306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3957f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3958349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3959349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3962f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3967054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
3968054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
3969054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
3970054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3971054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3972054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3973054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3974054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
3975054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
3976054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
3977054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3978054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3979054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3980054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3996349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3997349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4005054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4006c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4007054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4008054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4009054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4010054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4011054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4013349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
40143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4015349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4017349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4018349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4027349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4028349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
40323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4043c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4044c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4045c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4046c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4047c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4048c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4049c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4050349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4051349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40647a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4065d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4066d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4067d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4068d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4069d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4070d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4071d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4072349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4073349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4091496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4092496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4093496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4094496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4095496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4096496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4097496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4098496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4099496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4100496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4101496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4102a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4103a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4104a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4105a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4106a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4107a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4108a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4109a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4110a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4111a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4112a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4113a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4114a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4115a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4116a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4117a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4118a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
41207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
41216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
41237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
41247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
41257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4136530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4137a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4138a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4139a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4140a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4141a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4142a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4143a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4144a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4145a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4146a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4147a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4150a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4151a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4152a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4153a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4154a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4155a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4156e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4157e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4158e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4159e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4160b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4161b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4162e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4163e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4164e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4165e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4166b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4167b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4168b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4169b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4170b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4171b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4172b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4173b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4174b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4175b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4176b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4177b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4178b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4179b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4180b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4181b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4182e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4183e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4184a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4185a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4186a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41876507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
41886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
41896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
41906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
41916507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
41926507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
41936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
41946507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
41956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
41966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
41976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
420531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4206054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4212349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
421531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
421631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
42183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4237f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4242f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4260349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4262349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
42633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
42803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4302cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4303cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4304cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
430529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4306cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4307cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4308cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
43095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4310d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4311755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4312755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4313755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4314755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4315755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4316755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4317755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4318755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4319cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
432531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
432631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4331349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4349f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
43505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
43515778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
43833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
438431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
438631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
43985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4404349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4405349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4406349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4407349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4408349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4409349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4410349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
44150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
44175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44250167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
44260167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4427bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4428bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4429bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4430bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4431bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4432bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4433bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
44873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
45153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4520f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
45477a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4548d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4549d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4558e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4559e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4560e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4561e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4562e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4574349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4575349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4576349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4577349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4578349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4579349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4580349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4581349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4582349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4584349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4585349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4586349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4587349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4588349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4589349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4590349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
46147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
46157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
46167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
46177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4625dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4626dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4627f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4628f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4629f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4630f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4636