ACodec.cpp revision e40cda70eec141fa05cbcca1de420fdb22b98be6
127c174483a8ae9688d5d4897c19074f62c7f1701James Dong/*
227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Copyright (C) 2010 The Android Open Source Project
327c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Licensed under the Apache License, Version 2.0 (the "License");
527c174483a8ae9688d5d4897c19074f62c7f1701James Dong * you may not use this file except in compliance with the License.
627c174483a8ae9688d5d4897c19074f62c7f1701James Dong * You may obtain a copy of the License at
727c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
827c174483a8ae9688d5d4897c19074f62c7f1701James Dong *      http://www.apache.org/licenses/LICENSE-2.0
927c174483a8ae9688d5d4897c19074f62c7f1701James Dong *
1027c174483a8ae9688d5d4897c19074f62c7f1701James Dong * Unless required by applicable law or agreed to in writing, software
1127c174483a8ae9688d5d4897c19074f62c7f1701James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1227c174483a8ae9688d5d4897c19074f62c7f1701James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327c174483a8ae9688d5d4897c19074f62c7f1701James Dong * See the License for the specific language governing permissions and
1427c174483a8ae9688d5d4897c19074f62c7f1701James Dong * limitations under the License.
1527c174483a8ae9688d5d4897c19074f62c7f1701James Dong */
1627c174483a8ae9688d5d4897c19074f62c7f1701James Dong
17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#define LOG_NDEBUG 0
18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#define LOG_TAG "ACodec"
19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/ACodec.h>
21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <binder/MemoryDealer.h>
23f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/hexdump.h>
25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ABuffer.h>
26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/ADebug.h>
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/foundation/AMessage.h>
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
30afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber#include <media/stagefright/MediaCodecList.h>
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/MediaDefs.h>
321173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <media/stagefright/NativeWindowWrapper.h>
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <media/stagefright/OMXClient.h>
341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber#include <media/stagefright/OMXCodec.h>
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber#include <media/hardware/HardwareAPI.h>
373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
41496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
42f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
43f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
46f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
170ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
187f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
194f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
198ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
199ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
206c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
258054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
259054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
267349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
277349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
278349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
360afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
361afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
364308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
369054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mMetaDataBuffersToSubmit(0) {
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
387dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
392f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
395f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
405a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
406a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
407a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
408a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
409a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4175778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4315778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4367a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
440f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
462054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
463054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
464054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
465054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
488ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
491afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
492afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
493afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
494afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
496308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
498ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
499ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
501ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
503ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
505308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
506308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
507308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
508308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
511ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5191065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5221065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
533eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
534eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
535eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
537eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
539eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
542eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
548054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
550054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
56929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5753c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5763c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5773c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5793c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5803c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5813c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5823c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6083c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
61129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
615054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
616258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
618054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
62129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
625258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
629054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
630054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
631258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
632258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
633258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
634258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
63629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
64629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
651054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
652054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
653054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
654054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
655054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
656054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
657054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
658054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
659054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
660054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
661054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
662054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
665054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
668054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
6698ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6701e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
67229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
67774006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
67874006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
679054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
68074006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
68174006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
68274006804065941841883c4b46ee785070164023fJamie Gennis
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
68729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
68874006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69274006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
69374006804065941841883c4b46ee785070164023fJamie Gennis
6943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
70674006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
708054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
709054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
710054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
721054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
722054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
723054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
724054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
725054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
726054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
727054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
728054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
729054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
730054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
731054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
732054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
733054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
734054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
735054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
736054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
737054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
738054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
739054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
740054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
741054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
742054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
743054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
747054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
748054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
749054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
750054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
751054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
752054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
753054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
754054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
755054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
756054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
763054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7871e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
796f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7978ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7981e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8001e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
80129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
802c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
803c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
819054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
820054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
821054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
822054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
823054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
824054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
825054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
826054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
827054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
828054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
829054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
830054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
831054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
832054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
833054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
834054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
835054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        struct VideoDecoderOutputMetaData metaData;
837054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        metaData.eType = kMetadataBufferTypeGrallocSource;
838054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        metaData.pHandle = oldest->mGraphicBuffer->handle;
839054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        memcpy(oldest->mData->base(), &metaData, sizeof(metaData));
840054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
841054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p stored in %p)",
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
843054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
844054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                metaData.pHandle, oldest->mData->base());
845054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
846054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
864349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8692ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
8702ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
8712ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
8722ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
900f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9302944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9312944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9322944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9332944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
940729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
941729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
942c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
943c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
944c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
945c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
95294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
95394705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
95494705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
95594705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
956ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
957ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
9582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
9592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
960ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
961ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
9965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10222f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10232f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10242f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1028d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1029d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1030d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1031d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1032d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1033d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1034d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1035308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1036308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1037d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1038308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1039308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1040308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1041d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1042308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
10533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
10543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
10553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
10563a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10573a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
10583a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
10593a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10603a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10613a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
10623a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
10633a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
10643a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
10653a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
10663a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
10673a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
10683a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1069308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1070308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1071308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1072308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1073308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1074308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1075308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1076308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1077308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1078308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1079308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1080308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1081308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1082308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1085308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1092054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1093054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            // allow failure
1098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1100054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1101054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1102054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1103054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1104054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
1105054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1106054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
111942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
112042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
112142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
112242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
112342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
112442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
112542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
112642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
112742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
112842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
112942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
113042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
113142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1138aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1142aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1143aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1144aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1145ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
11474471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
11484471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1150729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1152729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1154729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1155729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1156729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1157729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1158729de186450f78c099637e1fce743fe531862c52Andreas Huber
1159729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
11662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
11672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
11682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
11692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
11702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
11712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
11722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
11732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1174516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1175516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
11762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
11772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1178516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1179516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1180516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
11822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1183516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1184516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1185516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
11862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
11872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
11882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1189516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1190516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
11912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1192ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1193ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1194ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1195ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1196ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1197ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1198ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1199ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1200ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1202729de186450f78c099637e1fce743fe531862c52Andreas Huber
12034471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
12044471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
12054471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
12064471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
12078b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
12088b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
12098b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12109806555d3930be43e11106281dee354820ac1c88Andreas Huber
12118b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
12128b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
12138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
12148b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
12159806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
12169806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
12179806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
12189806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
12199806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
12209806555d3930be43e11106281dee354820ac1c88Andreas Huber
1221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1231f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1295aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1296aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1361aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1387ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1388ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1390ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1391ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1443729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1444729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1446729de186450f78c099637e1fce743fe531862c52Andreas Huber
1447729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1448729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1449729de186450f78c099637e1fce743fe531862c52Andreas Huber
1450729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1451729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1452729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1453729de186450f78c099637e1fce743fe531862c52Andreas Huber
1454729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1459729de186450f78c099637e1fce743fe531862c52Andreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1463729de186450f78c099637e1fce743fe531862c52Andreas Huber
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1468729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1469729de186450f78c099637e1fce743fe531862c52Andreas Huber
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1473729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1474729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1475729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1476729de186450f78c099637e1fce743fe531862c52Andreas Huber
14772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
14782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
14792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
14812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
14822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
14832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
14842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
14862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
14892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
14902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
14912f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
14922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
14932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
14942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
14952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
14962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
14972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
14982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
14992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
15002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
15012f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
15022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
15032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
15042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1505729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1506729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1507729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1508729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1509729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1510729de186450f78c099637e1fce743fe531862c52Andreas Huber
1511729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1512729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1513729de186450f78c099637e1fce743fe531862c52Andreas Huber
1514729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1515729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1516729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1517729de186450f78c099637e1fce743fe531862c52Andreas Huber
1518729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1519729de186450f78c099637e1fce743fe531862c52Andreas Huber
1520729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1521729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1522729de186450f78c099637e1fce743fe531862c52Andreas Huber
1523729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1524729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1525729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1526729de186450f78c099637e1fce743fe531862c52Andreas Huber
1527729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1528729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1529729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1530729de186450f78c099637e1fce743fe531862c52Andreas Huber
1531729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1532729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1533729de186450f78c099637e1fce743fe531862c52Andreas Huber
1534729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1535729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1536729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1537729de186450f78c099637e1fce743fe531862c52Andreas Huber
1538729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1539729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1540729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1541729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1542729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1543729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1544729de186450f78c099637e1fce743fe531862c52Andreas Huber
1545c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1546c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1547729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1548729de186450f78c099637e1fce743fe531862c52Andreas Huber
1549729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1550729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1551729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1552729de186450f78c099637e1fce743fe531862c52Andreas Huber
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1612f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
163794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
163894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1663e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
18640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
18650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
18660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
18670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
18690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
18710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
18740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
18770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
18800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
18810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
18820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
18830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
18860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
18880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
18890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
18900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
18910dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
18920dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
18930dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
18940dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
18950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
18960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
18970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
18980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
18990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
191296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
191396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
191496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
191596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
191696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
191796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
191896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
191996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
192796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
192896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
199296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
200896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
200996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
206896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
208596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
20960dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
20970dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
20980dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
20990dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
21000dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
21010dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
21020dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
21030dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
21040dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
21050dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21100dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
21387c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
21397c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
21407c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
218296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
221196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
221296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
222596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2295f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2304d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2305d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2306d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2307d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2308d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2309d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2310d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2311d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2312d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2313d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2314d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2315d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2316d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2317d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
23187e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
23197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
23207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
23227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
23237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
23267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
23277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23287e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
23307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23327e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
23337e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
23347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
23357e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23367e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23377e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
23387e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
23397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
23407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
23417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23427e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
23437e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
23447e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
23457e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23467e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
23477e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23487e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
23497e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
23507e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
23517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
23527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
23537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2354f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
23613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2371f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2376f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2381f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2391577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
239231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
239331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
239431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
239531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
239631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
239731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
239831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
239931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
240031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
240131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
240231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
240431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
240531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
240631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
240731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
240831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
240931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
242031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
242131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
242231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2456577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2457577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2458577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2459577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2460577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2461577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2462e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
246331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
246431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
246531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
246631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
246731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
246831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
246931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
247031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2471e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2472e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2474e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2475e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2476e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2477e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2478e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2481e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2482e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
248314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
248614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
248714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
248814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
248914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
249014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
249114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
250114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
250214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
250314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
250614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
250714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
250814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
25138b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
25158b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
25169806555d3930be43e11106281dee354820ac1c88Andreas Huber
2517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
25399806555d3930be43e11106281dee354820ac1c88Andreas Huber
2540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
258031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
258231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
258431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
258531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
258631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
258831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
259031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
259131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
25925778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2593cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2594cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2595cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2597cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2598cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2599cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2626bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2627bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2628bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2629bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2630bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2631bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2632bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2633bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2634bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2635bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2636bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2637bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2638bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2639bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2640bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2641bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2642bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2643bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2644bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2645bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2646bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2647bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2648bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2649bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2650bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2651bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2652bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2653bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2654bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2655bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2656bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2657bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2658bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2659bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2660bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2661bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
26621e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
26631e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2664bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2665bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2666bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2667bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2668bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2669bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2670bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2671bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2672bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2673bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2674bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2675bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2676bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2677bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2678bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2679bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2680bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2681bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2682bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2683bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2684bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2685bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2686bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
26911e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2694bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2695bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2696bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2697bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2698bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2699bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2700bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2701bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2702bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2703bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2704bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2705bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
27061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2707bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2708bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2709bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2710bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2711bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2712bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2713bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2714bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2715bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2716bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2717bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2718bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2719bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2720bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2721bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2722bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2723bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2724bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2725bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2726bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2727bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2728bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2729bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2730bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2731bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2732bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2733bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2734bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2735bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2736bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2739eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2740eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2741eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2742496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2743496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2744496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2745496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2746496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2747496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2748496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2749496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2750496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2751496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2752496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2753496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2754496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2755496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2756496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2757496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2758496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2759496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2760eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2761eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2762eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2763eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2764eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2765eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2766eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2767eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2768eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2769eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2770eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2771eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2772eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2773eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2774eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2775eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2776eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2777eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2778eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2780f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2785f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2789f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
28097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
28107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
28117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
28127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
28137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
28147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
28157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2816ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2817ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2818ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2819ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2820ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2821ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2822ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
28470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
28480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
28490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
28500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
28510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
28520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
28530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
28540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
28550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
28560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
29063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
291229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2914cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2919f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
29203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2921349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2922349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2929d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2930d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2931d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2932d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2933d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2934d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2935d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2936d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2937d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
293896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
293996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
294096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2943d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2944d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2946d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2968f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2972f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
29802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
29985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
29995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
30043831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
30053831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
30062d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
30075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
30085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
30125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
30135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
30145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
30155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
30165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3028dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3029dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3030dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3031dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
30505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
30515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
30525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3063078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
30643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3065078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
30665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
30675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
30685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3069078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3070d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3071d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3072d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3073d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
30743856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3075078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3077078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3078349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3086054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3087054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3088054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3089054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3090054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3091054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3092054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3093054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3094054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3095054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3096054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3097054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3098054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3099054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
31125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
31135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
31145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
31165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
31185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
31195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3121dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
31223856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3123dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3124dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3125dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
31263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3127dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3128dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3131349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3132349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3145dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
31925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
31935778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3194349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3196d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3197d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3198d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3199d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3200d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3201d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3202d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3203d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3204d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3205d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3206d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3207d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3208d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3217054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
32295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
32305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3231349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
32325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
32335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
32345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
32375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
32385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
323931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3240577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3241577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3242577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3243e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3244577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
32455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3247308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3248308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3249308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3250308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3251308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3252308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3253308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3254308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3255308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3256496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
325721ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3258496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3259496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3260496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
32615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
326221ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32648b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
32658b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
32668b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
32675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
32722d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
32735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3288dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3318577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3319577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3320577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3321577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3322577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3323577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3324577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
33276aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
33286aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
33341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3335cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3336cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
33375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3338cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3339cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3370c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
33713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3372c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3373349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3374c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3375c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3377c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3378c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3396f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3400c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3402ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3403ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3404ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3405ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3406ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3407ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3408ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3409ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3410ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3411ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3412ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3413308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3414ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3416c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
34355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3448c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3458c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3473c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
34785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
34805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3486ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3487ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3488ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3489ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3490ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3491ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3492ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3493ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3494ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3495e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
34965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3500d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
35015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3502e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3503e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3504e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3505afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3506e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3507e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3508e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3509afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
35105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
35115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
35145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
35155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
35195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3523e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
35245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
35251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
35271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
35281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
35301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3531e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3532e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3534078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3535078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3536078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
35371065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3538078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
35411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
35421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
35431065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
35441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
35451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
35461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3547c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
35485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
35495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
35525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3554c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3555cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3557c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3563ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3564ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3565ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3566ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3567ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3568ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3569afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
35745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
35755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
35765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
35775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
35785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3581c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
35835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3586c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3589c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3590c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3591c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3592c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3593c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3594f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3595f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3596f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3597f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3598f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3599054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3600054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3601054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3602c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3607c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3613c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3614c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3615c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3616c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3618c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3630c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3631c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3632c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3633c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3634c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
36357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
36367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
36377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
36387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
36397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
36407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
36417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3647c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3655c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3656c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3657c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3658c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3659c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3660c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3661c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3662c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3663c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3664c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3665c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3666c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3667c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3668c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3669c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3670c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3672c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3678c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
36805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
36835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
36855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
36865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
36885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3690c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3691c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3692c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
36935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
36955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3698386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
36995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
37001173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
37011173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
37021173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
37031173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
37041ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
37051ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
37061ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
37071ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
37217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
37227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
37237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
37257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
37267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
37287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
37297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
37307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
37317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
37327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
37337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
37347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
37357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
37367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
37377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
37387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
37397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
37407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
37417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
37427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
37437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
37447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
37457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
37475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
37485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
37505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
37633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3765cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3766cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
376729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3768cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3769cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3770cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
37715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
377291bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
377391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3774cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3787f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
37966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
37976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
37986507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
37996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
38016463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
38026463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38036463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
38046463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38056463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38066463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
38076463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
38086463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
38096463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
38106463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
38116463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
38126463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
38136463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
38146463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
38156463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3845f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3849f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
38503856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3853f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3861d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3862d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3863d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3864d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3865d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3866d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3867d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3868d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3869d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3870d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3871d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3872d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3873d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3874d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3875d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3876d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
38776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
38786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
38796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
38806507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
38816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
38826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3888f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3909f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3910349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3911349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3914f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3919054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
3920054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
3921054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
3922054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3923054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3924054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3925054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
3926054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
3927054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
3928054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
3929054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3930054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3931054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3932054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
3933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3948349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3949349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3957054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
3958054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
3959054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
3960054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    } else {
3961054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitRegularOutputBuffers();
3962054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
3963054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
3964054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3966349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
39673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3968349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3969349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3970349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3971349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3972349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3980349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3981349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
39853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3998c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3999c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4000c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4001c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4003349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4004349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
40177a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4018d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4019d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4020d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4021d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4022d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4023d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4024d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4025349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4026349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4044496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4045496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4046496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4047496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4048496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4049496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4050496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4051496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4053496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4055a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4056a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4057a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4058a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4059a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4060a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4061a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4062a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4063a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4064a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4065a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4066a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4067a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4068a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4069a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4070a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4071a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
40727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
40737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
40746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
40767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
40777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
40787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
4090a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4091a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4092a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4093a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4094a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4095a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4096a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4097a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4098a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4099a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4100a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4101a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4102a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4103a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4104a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4105a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4106a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4107a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4108a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4109e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4110e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4111e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4112e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4113e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        CHECK_EQ((status_t)OK,
4114e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                 mOMX->setInternalOption(
4115e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4116e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4117e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4118e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4119e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     sizeof(suspend)));
4120e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4121e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4122a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4123a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4124a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
41256507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
41266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
41276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
41286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
41296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
41306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
41316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
41326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
41336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
41346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
41356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
414331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4144054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4150349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
415331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
415431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
41563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4180f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4198349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4200349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
42013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4203349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
42183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4240cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4241cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4242cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
424329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4244cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4245cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4246cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
42475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4248d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4249755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4250755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4251755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4252755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4253755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4254755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4255755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4256755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4257cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
426331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
426431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
42653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4271349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
42885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
42895778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
43213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
432231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
43235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
432431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
43365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4342349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4343349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4344349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4345349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4346349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4347349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4348349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
43530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
43555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4364bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4365bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4366bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4367bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4368bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4369bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4370bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4382f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4391f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4423f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
44243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4427f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4447f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4451f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
44523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
44847a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4485d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4486d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4495e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4496e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4497e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4498e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4499e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4511349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4512349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4513349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4514349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4516349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4517349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4518349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4519349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
45203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4521349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4522349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4523349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4526349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4527349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
45517e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
45527e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
45537e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
45547e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4563dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4564f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4565f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4566f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4567f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4573