ACodec.cpp revision 94705aff3c9eef58cbb72ec6fe5d2dcfd9481646
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
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
265349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
266349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
275349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
276349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
357f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
358afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
362308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3639806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3649806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3659806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3669806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMask(0) {
368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
382dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
401a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
402a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
403a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
404a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
405a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4065778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
430f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4317a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
435f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
445496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
446496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
447496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
448496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = allocateOutputBuffersFromNativeWindow();
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
479ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
480ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
482afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
483afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
484afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
485afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
4861065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
487308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
488308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
489ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
490ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
491ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
492ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
493ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
494ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
495ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
496308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
497308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
498308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
499308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
500ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
502ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
504ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
505ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
506ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
524eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
525eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
526eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
528eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
530eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
533eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
539f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
55829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5643c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5653c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5663c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5675ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5683c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5693c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
5703c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
5713c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
575bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
60029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
604258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    int minUndequeuedBufs = 0;
605258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
606258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
607258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            &minUndequeuedBufs);
608258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
609258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
61029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
611258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
612258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
613258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
614258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
615258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // XXX: Is this the right logic to use?  It's not clear to me what the OMX
616258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // buffer counts refer to - how do they account for the renderer holding on
617258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    // to buffers?
618258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
619258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
620258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
621258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
622258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
623258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
624258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        if (err != OK) {
62529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
626258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                    mComponentName.c_str(), newBufferCount, err);
627258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
628258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
629258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
630258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
6403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
64574006804065941841883c4b46ee785070164023fJamie Gennis    for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
6468ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
6471e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
64929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
65474006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
65574006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
65621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen        info.mData = new ABuffer(NULL /* data */, def.nBufferSize /* capacity */);
65774006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
65874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
65974006804065941841883c4b46ee785070164023fJamie Gennis
660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
66429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
66574006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66974006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
67074006804065941841883c4b46ee785070164023fJamie Gennis
6713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
68374006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // Return the last two buffers to the native window.
686258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        cancelStart = def.nBufferCountActual - minUndequeuedBufs;
687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelEnd = def.nBufferCountActual;
688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
698f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
7051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
714f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
7158ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
7161e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
7171e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
71829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
719c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
720c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mGraphicBuffer->handle == buf->handle) {
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
751349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
7562ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
7572ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
7582ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
7592ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
767f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
787f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
8172944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
8182944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
8192944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
8202944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
827729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
828729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
829c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
830c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
831c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
832c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
83994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
84094705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
84194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
84294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
843ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
844ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
8452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
8462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
847ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
848ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
8835ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
9092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
9102f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
9112f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
915d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
916d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
917d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
918d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
919d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
920d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
921d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
922308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
923308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
924d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
925308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
926308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
927308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
928d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
929308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
9303a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
9313a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
9323a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
9333a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
9343a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
9353a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
9363a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
9373a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
9383a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9393a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
9403a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
9413a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
9423a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
9433a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9443a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
9453a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
9463a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9473a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9483a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
9493a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
9503a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
9513a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
9523a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
9533a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
9543a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
9553a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
956308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
957308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
958308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
959308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
960308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
961308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
962308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
963308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
964308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
965308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
966308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
967308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
968308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
969308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
970308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
971308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
972308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
973308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
974308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
975308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
976308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
98842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
98942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
99042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
99142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
99242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
99342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
99442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
99542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
99642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
99742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
99842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
99942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
100042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1007aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1008ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1009ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1010ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1011aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1012aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1013aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1014ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1015ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
10164471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
10174471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1019729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1021729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1023729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1024729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1025729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1026729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1027729de186450f78c099637e1fce743fe531862c52Andreas Huber
1028729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10342f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
10352f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
10362f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
10372f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
10382f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
10392f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
10402f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
10412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
10422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1043516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1044516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
10452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
10462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1047516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1048516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1049516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
10502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
10512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1052516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1053516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1054516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
10552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
10562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
10572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1058516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1059516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
10602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1061ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1062ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1063ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1064ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1065ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1066ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1067ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1068ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1069ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1071729de186450f78c099637e1fce743fe531862c52Andreas Huber
10724471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
10734471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
10744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
10754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
10768b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
10778b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
10788b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10799806555d3930be43e11106281dee354820ac1c88Andreas Huber
10808b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
10818b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
10828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
10838b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
10849806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
10859806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
10869806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
10879806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
10889806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
10899806555d3930be43e11106281dee354820ac1c88Andreas Huber
1090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1100f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1164aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1165aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1230aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1256ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1257ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1258ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1260ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1312729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1313729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1315729de186450f78c099637e1fce743fe531862c52Andreas Huber
1316729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1317729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1318729de186450f78c099637e1fce743fe531862c52Andreas Huber
1319729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1320729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1321729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1322729de186450f78c099637e1fce743fe531862c52Andreas Huber
1323729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1328729de186450f78c099637e1fce743fe531862c52Andreas Huber
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1332729de186450f78c099637e1fce743fe531862c52Andreas Huber
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1337729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1338729de186450f78c099637e1fce743fe531862c52Andreas Huber
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1342729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1343729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1344729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1345729de186450f78c099637e1fce743fe531862c52Andreas Huber
13462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
13472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
13482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
13502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
13512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
13522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
13532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
13552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
13562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
13572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
13582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
13612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
13622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
13632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
13642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
13652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
13662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
13672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
13682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
13692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
13702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
13712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
13722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
13732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1374729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1375729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1376729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1377729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1378729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1379729de186450f78c099637e1fce743fe531862c52Andreas Huber
1380729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1381729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1382729de186450f78c099637e1fce743fe531862c52Andreas Huber
1383729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1384729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1385729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1386729de186450f78c099637e1fce743fe531862c52Andreas Huber
1387729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1388729de186450f78c099637e1fce743fe531862c52Andreas Huber
1389729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1390729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1391729de186450f78c099637e1fce743fe531862c52Andreas Huber
1392729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1393729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1394729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1395729de186450f78c099637e1fce743fe531862c52Andreas Huber
1396729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1397729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1398729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1399729de186450f78c099637e1fce743fe531862c52Andreas Huber
1400729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1401729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1402729de186450f78c099637e1fce743fe531862c52Andreas Huber
1403729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1404729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1405729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1406729de186450f78c099637e1fce743fe531862c52Andreas Huber
1407729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1408729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1409729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1410729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1411729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1412729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1413729de186450f78c099637e1fce743fe531862c52Andreas Huber
1414c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1415c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1416729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1417729de186450f78c099637e1fce743fe531862c52Andreas Huber
1418729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1419729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1420729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1421729de186450f78c099637e1fce743fe531862c52Andreas Huber
1422f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1433f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1434f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1435f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1436f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1481f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1499e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1500e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1501e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1502e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1503e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
150694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
150794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1524e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1525e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1526e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1527e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1528e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17320dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
17330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
17340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
17350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
17360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
17380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
17400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
17410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
17420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
17430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
17440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
17450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
17460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
17470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
17490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
17500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
17510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
17520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
17530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
17540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
17550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
17570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
17580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
17590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
17600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
17610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
17620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
17640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
17650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
17660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
17670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
17680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
178096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
178196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
178296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
178396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
178496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
178596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
178696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
178796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
178896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
179696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
179796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
186196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
187796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
187896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
193796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
195396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
195496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
19650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
19660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
19670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
19680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
19690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
19700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
19710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
19720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
19730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
19740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
20077c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
20087c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
20097c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
205196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
208196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
209496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2126f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2164f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2173d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2174d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2175d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2176d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2177d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2178d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2179d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2180d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2181d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2182d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2183d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2184d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2185d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2186d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
21877e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
21887e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
21897e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
21907e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
21917e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
21927e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
21937e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
21947e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
21957e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
21967e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
21977e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
21987e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
21997e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
22007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
22017e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
22027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
22037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
22047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
22057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
22067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    int minUndequeuedBufs = 0;
22077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    status_t err = mNativeWindow->query(
22087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
22097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            &minUndequeuedBufs);
22107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
22117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (err != OK) {
22127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
22137e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber                mComponentName.c_str(), strerror(-err), -err);
22147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
22157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        minUndequeuedBufs = 0;
22167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
22177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
22187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
22197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
22207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
22217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
22227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2223f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
22303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2240f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2245f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2250f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2260577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
226131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
226231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
226331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
226431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
226531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
226631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
226731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
226831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
226931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
227031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
227131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
227231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
227331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
227431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
227531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
227631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
227731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
227831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2279e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2280e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2281e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2282e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2283e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2284e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2285e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2286e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2287e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2288e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
228931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
229031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
229131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2292e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2293e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2294e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2295e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2296e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2297e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2298e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2299e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2300e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2301e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2302e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2303e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2304e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2305e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2306e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2307e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2309e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2310e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2311e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2325577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2326577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2327577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2328577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2329577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2330577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
233231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
233331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
233431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
233531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
233631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
233731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
233831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
233931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            switch (audioDef->eEncoding) {
2341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2347e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
235214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2354e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
235514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
235614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
235714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
235814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
235914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
236014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2361e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2362e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2363e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2364e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2365e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2366e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2367e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2368e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2369e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
237014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
237114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
237214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2373e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2374e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
237514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
237614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
237714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2378e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2379e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2380e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2381e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
23828b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
23848b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
23859806555d3930be43e11106281dee354820ac1c88Andreas Huber
2386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2388e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2389e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2396e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2397e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2398e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2399e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2400e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2401e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2402e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2403e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2404e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2405e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2406e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
24089806555d3930be43e11106281dee354820ac1c88Andreas Huber
2409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
244931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
245031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
245131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
245231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
245331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
245431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
245531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
245631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
245731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
245831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
245931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
246031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
24615778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2462cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2463cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2464cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2466cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2467cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2468cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2469bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2470bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2471bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2472bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2473bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2474bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2475bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2476bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2477bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2478bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2479bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2480bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2481bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2482bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2483bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2484bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2485bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2486bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2487bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2488bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2489bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2490bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2491bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2492bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2493bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2494bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2495bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2496bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2497bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2498bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2499bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2500bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2501bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2502bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2503bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2504bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2505bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2506bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2507bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2508bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2509bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2510bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2511bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2512bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2513bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2514bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2515bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2516bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2517bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2518bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2519bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2520bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2521bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2522bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2523bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2524bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2525bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2526bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2527bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2528bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2529bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2530bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
25311e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
25321e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2533bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2534bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2535bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2536bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2537bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2538bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2539bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2540bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2541bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2542bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2543bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2544bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2545bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2546bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2547bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2548bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2549bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2550bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2551bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2552bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2553bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2554bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2555bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2556bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2557bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2558bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2559bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
25601e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2561bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2562bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2563bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2564bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2565bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2566bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2567bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2568bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2569bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2570bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2571bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2572bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2573bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2574bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
25751e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2576bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2577bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2578bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2579bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2580bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2581bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2582bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2583bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2584bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2585bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2586bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2587bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2588bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2589bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2590bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2591bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2592bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2593bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2594bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2595bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2596bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2597bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2598bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2599bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2600bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2601bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2608eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2609eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2610eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2611496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2612496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2613496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2614496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2615496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2616496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2617496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2618496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2619496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2620496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2621496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2622496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2623496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2624496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2625496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2626496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2627496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2628496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2629eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2630eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2631eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2632eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2633eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2634eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2635eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2636eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2637eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2638eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2639eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2640eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2641eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2642eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2643eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2644eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2645eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2646eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2647eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2648eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2649f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2654f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(OMX_U32 portIndex) {
2655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2658f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
2669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
2673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
2675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
26777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
26787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
26797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
26807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
26817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
26827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
26837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
26847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2685ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
2686ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
2687ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
2688ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
2689ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
2690ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
2691ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
2692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2699f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
2700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
2701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
2702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
2704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
2705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
2706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
2708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
2709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
2711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
2712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
2713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
2714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
27150af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
27160af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
27170af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
27180af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
27190af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
27200af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
27210af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
27220af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
27230af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
27240af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
27250af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
2726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
2727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
2728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
2729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
2730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
2733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
2738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
2741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
2743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
2744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
2746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
2747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
2748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
2749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
2751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
2752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
2753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
2754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
2755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
2756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
2758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
2759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
2760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
2761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
2762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
2763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
2764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
2768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2772f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
2773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
2774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
27753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
2776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
2777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
2779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
2782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2783cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
2784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2788f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
27893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
2790349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
2791349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
2793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
2794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
2796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2798d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
2799d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
2800d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
2801d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
2802d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
2803d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
2804d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
2805d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
2806d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
280796fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
280896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
280996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
2810d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
2811d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
2812d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2813d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
2814d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
2815d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
2824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
2827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
2829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
2830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2837f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
2838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
2839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
2840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
2843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
2845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
2846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
2847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
28492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
2850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
2852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
2853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
2855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
2857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
2859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2861f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
2862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
2863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
2864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
2866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
28675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
28685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28692d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
2870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
2871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] saw error %d instead of an input buffer",
28733831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber             mCodec->mComponentName.c_str(), err);
28743831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
28752d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
28765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
28775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
2878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
28805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
28815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
28825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
28835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
28845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
28855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
2887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
2888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
2890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
2892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
2894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
2895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
28965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
2897dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
2898dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
2899dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
2900dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
2902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
2906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
29075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
2908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
2909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
2912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
2914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
2915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
2916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
29195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
29205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
29215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2922f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
2923d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
2924d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
2925d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
2926d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
2927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
2929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
2930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
2931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2932078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
29333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
2934078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
29355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
29365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
29375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
2938078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
2939d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2940d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
2941d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2942d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
29433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
2944078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
2945d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2946078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
2947349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2948d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
2949d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
2950d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
2951d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
2952d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
2953d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
2954d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
2955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
2960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
2961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
2962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
29675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
29685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
29695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
29705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
29715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
29725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
29735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
29745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
2976dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
29773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
2978dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
2979dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
2980dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
29813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
2982dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
2983dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
2984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
29853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
2986349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
2987349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3000dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3011f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *platformPrivate,
3046f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        void *dataPtr) {
30475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
30485778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3049349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3051d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3052d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3053d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3054d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3055d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3056d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3057d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3058d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3059d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3060d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3061d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3062d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3063d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3064d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3065d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3066d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
30825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
30835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
30845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3085349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
30865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
30875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
30885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
30915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
30925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
309331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3094577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3095577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3096577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mCodec->mSentFormat) {
3098577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
30995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3101308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3102308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3103308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3104308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3105308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3106308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3107308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3108308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3109308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3110496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
311121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3112496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3113496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3114496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
31155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
311621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31188b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
31198b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
31208b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
31215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
31245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
31255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
31262d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
31275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
31345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
31355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
31385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
31395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3142dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3172577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3173577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3174577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3175577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3176577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3177577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3178577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
31816aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
31826aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && (info->mData == NULL || info->mData->size() != 0)) {
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
31865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
31881e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3189cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3190cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
31915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3192cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3193cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3211f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3224c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
32253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3226c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3227349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3228c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3229c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3231c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3232c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3250f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3254c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3255c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3256ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3257ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3258ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3259ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3260ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3261ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3262ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3263ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3264ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3265ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3266ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3267308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3268ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3269c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3270c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
32845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
32855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
32865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
32875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
32885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
32895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3292c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3293c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3294c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3295c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3296c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3302c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3312c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3322f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3324c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3325c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3326c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3327c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
33285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
33295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3330c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
33315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
33325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3333c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3340ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3341ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3342ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3343ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3344ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3345ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3346ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3347ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3348ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3349e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
33555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3356e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3357e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3358e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3359afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3360e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3361e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3362e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
33645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
33655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
33665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
33685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
33695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
33705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
33715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
33735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
33745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
33755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
33765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3377e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
33785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33791065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33801065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
33811065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
33821065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33831065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
33841065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3385e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3386e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3388078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3389078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3390078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
33911065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3392078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33941065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
33951065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
33961065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
33971065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
33981065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
33991065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
34001065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3401c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
34045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
34055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
34065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
34075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3408c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3409cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3410c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3411c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3413ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3414f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3415f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3417ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3418ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3419ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3420ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
3421ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3422ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3423afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
34285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
34295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
34305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
34315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3433c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3434c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3435c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3436c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3441c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3446c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3447c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3448f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3449f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3450f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3451f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3452f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3457c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3458c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3459c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3460c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3461c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3462c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3463c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3464c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3465c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3466c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3467c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3473c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3475c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3476c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3477c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3478c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
34867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
34877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
34887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
34897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
34907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
34917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
34927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3496c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3497c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3498c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3499c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3500c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3501c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3502c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3503c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3504c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3507c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3510c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3511c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3514c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3515c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3516c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3517c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3518c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3519c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3520c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3521c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3522c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3523c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3524c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3525c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3526c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3527c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3528c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3529c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
35305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
35315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
35325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
35345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
35375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
35395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3541c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3542c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3543c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
35445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3545c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
35465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3549386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
35505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
35511173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
35521173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
35531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
35541173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
35551ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
35561ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
35571ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
35581ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
35665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3567c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3568c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
35705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
35727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        const sp<AMessage> &msg) {
35737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
35747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
35757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
35767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
35777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
35787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
35797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
35807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
35817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
35827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
35837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
35847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
35857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
35867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
35877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
35887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
35897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
35907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
35917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
35927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
35937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
35947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
35957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
35967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
35985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
35995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
36005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
36015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
3605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3609f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
36143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
3615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3616cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
3617cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
361829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
3619cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
3620cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
3621cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
36225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
362391bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
362491bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
3625cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
36476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
36486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
36496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
36506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
36516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
36526463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
36536463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
36546463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
36556463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
36566463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
36576463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
36586463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
36596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
36606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
36616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
36626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
36636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
36646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
36656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
36666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3692f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3693f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3696f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
3697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3700f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
37013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3712d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
3713d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3714d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
3715d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3716d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3717d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3718d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
3719d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
3720d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
3721d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3722d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3723d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
3724d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
3725d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
3726d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
3727d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
37286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
37296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
37306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
37316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
37326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
37336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3760f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
3761349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
3762349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
3763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3765f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::submitOutputBuffers() {
3771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
3772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
3773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
3780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
3786349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
3787349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
3790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3795f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
3796349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
37973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
3798349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
3799349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3800349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
3801349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
3802349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
3804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
3806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
3807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
3808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
3810349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3811349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
3812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3814f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
38153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
3816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
3818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3820f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
3821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
3825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
3831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
3832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3833349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
3837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
3840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
38477a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
3848d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
3849d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
3850d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
3851d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
3852d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
3853d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
3854d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
3855349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
3856349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
3858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
3859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
3860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
3862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
3867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
3869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3874496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
3875496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
3876496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
3877496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
3878496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
3879496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
3880496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3881496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
3882496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
3883496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
3884496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3885a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
3886a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
3887a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
3888a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
3889a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3890a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
3891a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3892a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
3893a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
3894a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
3895a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
3896a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
3897a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3898a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
3899a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
3900a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
3901a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
39027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
39037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
39046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
39057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
39067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
39077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
39087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
3911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3917a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
3918a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
3919a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    if (params->findInt32("videoBitrate", &videoBitrate)) {
3920a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
3921a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
3922a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
3923a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
3924a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3925a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
3926a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
3927a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
3928a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
3929a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
3930a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3931a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
3932a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
3933a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
3934a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3935a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
3936a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
3937a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
3938a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
3939a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
3940a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
3941a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
39426507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
39436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
39446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
39456507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
39466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
39476507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
39486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
39496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
39506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
39516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
39526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
3953f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
3954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
3956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
3957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
3959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
3961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
3962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
3964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3966349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
3967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
396931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
397031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
3971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
39723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
3973f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
3974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
3980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
3982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
3986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3989f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3991f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
3992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
3993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3996f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
3999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4007f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4014349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4016349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
40173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4018349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4019349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
40343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4047f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4056cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4057cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4058cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
405929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4060cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4061cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4062cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
40635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4064d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4065755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4066755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4067755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4068755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4069755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4070755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4071755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4072755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4073cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
408031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
40813856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4084349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4085349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4086349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4087349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4103f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
41373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
413831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
41395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
414031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
41525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4158349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4159349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4160349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4161349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4162349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4163349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4164349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
41690af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
41715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4179bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (mCodec->mFlags & kFlagIsSecure && mCodec->mNativeWindow != NULL) {
4180bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4181bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4182bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4183bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4184bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4185bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4186bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4207f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4239f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
42403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4251c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4263f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
42683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4278f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4279f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4280f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
43007a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4301d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4302d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4311e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4312e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4313e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4314e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4315e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4327349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4328349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4329349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4331349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4334349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
43363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4337349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4338349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4339349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4340349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4341349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4342349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4343349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4357f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4363f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
43677e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
43687e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
43697e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
43707e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4379dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4380f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4381f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4382f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4383f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4389