ACodec.cpp revision 5e184b0d12f1ec436246a391da8d9355cc21ee08
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
3897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_AudioExt.h>
39f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <OMX_Component.h>
4097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu#include <OMX_IndexExt.h>
41f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#include "include/avc_utils.h"
43496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
44f933441648ef6a71dee783d733aac17b9508b452Andreas Hubernamespace android {
45f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46f933441648ef6a71dee783d733aac17b9508b452Andreas Hubertemplate<class T>
47f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatic void InitOMXParams(T *params) {
48f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nSize = sizeof(T);
49f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMajor = 1;
50f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nVersionMinor = 0;
51f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nRevision = 0;
52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    params->nVersion.s.nStep = 0;
53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
55f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct CodecObserver : public BnOMXObserver {
56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CodecObserver() {}
57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void setNotificationMessage(const sp<AMessage> &msg) {
59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mNotify = msg;
60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // from IOMXObserver
63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onMessage(const omx_message &omx_msg) {
64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> msg = mNotify->dup();
65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setInt32("type", omx_msg.type);
67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->setPointer("node", omx_msg.node);
68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        switch (omx_msg.type) {
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EVENT:
71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("event", omx_msg.u.event_data.event);
73f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data1", omx_msg.u.event_data.data1);
74f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32("data2", omx_msg.u.event_data.data2);
75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::EMPTY_BUFFER_DONE:
79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
84f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            case omx_message::FILL_BUFFER_DONE:
85f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            {
86f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
87f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "buffer", omx_msg.u.extended_buffer_data.buffer);
88f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
89f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_offset",
90f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_offset);
91f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "range_length",
93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.range_length);
94f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt32(
95f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "flags",
96f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.flags);
97f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setInt64(
98f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "timestamp",
99f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.timestamp);
100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "platform_private",
102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.platform_private);
103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                msg->setPointer(
104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        "data_ptr",
105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        omx_msg.u.extended_buffer_data.data_ptr);
106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            default:
110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                TRESPASS();
111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        msg->post();
115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
117f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual ~CodecObserver() {}
119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
120f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> mNotify;
122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::BaseState : public AState {
129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState(ACodec *codec, const sp<AState> &parentState = NULL);
130f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
131f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    enum PortMode {
133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        KEEP_BUFFERS,
134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        RESUBMIT_BUFFERS,
135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        FREE_BUFFERS,
136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ACodec *mCodec;
139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void postFillThisBuffer(BufferInfo *info);
150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
151f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXMessage(const sp<AMessage> &msg);
153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool onOMXFillBufferDone(
157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID,
158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            size_t rangeOffset, size_t rangeLength,
159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            OMX_U32 flags,
160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs,
161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate,
162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr);
163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void getMoreInputDataIfPossible();
165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BaseState);
167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
171ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberstruct ACodec::DeathNotifier : public IBinder::DeathRecipient {
172ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DeathNotifier(const sp<AMessage> &notify)
173ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        : mNotify(notify) {
174ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
175ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
176ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual void binderDied(const wp<IBinder> &) {
177ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mNotify->post();
178ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
179ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
180ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprotected:
181ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    virtual ~DeathNotifier() {}
182ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
183ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huberprivate:
184ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> mNotify;
185ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
186ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(DeathNotifier);
187ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber};
188ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
189f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::UninitializedState : public ACodec::BaseState {
190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    UninitializedState(ACodec *codec);
191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
192f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
196f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void onSetup(const sp<AMessage> &msg);
198c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onAllocateComponent(const sp<AMessage> &msg);
199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
200ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<DeathNotifier> mDeathNotifier;
201ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
207c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstruct ACodec::LoadedState : public ACodec::BaseState {
208c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    LoadedState(ACodec *codec);
209c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprotected:
211c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
212c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    virtual void stateEntered();
213c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberprivate:
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    friend struct ACodec::UninitializedState;
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool onConfigureComponent(const sp<AMessage> &msg);
2187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    void onCreateInputSurface(const sp<AMessage> &msg);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onStart();
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    void onShutdown(bool keepComponentAllocated);
221c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
222c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
223c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber};
224c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
225c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
226c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
227f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::LoadedToIdleState : public ACodec::BaseState {
228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    LoadedToIdleState(ACodec *codec);
229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
230f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
235f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t allocateBuffers();
237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
243f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToExecutingState : public ACodec::BaseState {
244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToExecutingState(ACodec *codec);
245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
246f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
251f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
257f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingState : public ACodec::BaseState {
258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingState(ACodec *codec);
259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
260054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitRegularOutputBuffers();
261054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    void submitOutputMetaBuffers();
262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void submitOutputBuffers();
263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Submit output buffers to the decoder, submit input buffers to client
265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // to fill with data.
266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void resume();
267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
268349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    // Returns true iff input and output buffers are in play.
269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool active() const { return mActive; }
270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
271f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
278f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
279349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    bool mActive;
280349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
281f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
282f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
286f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::OutputPortSettingsChangedState : public ACodec::BaseState {
287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OutputPortSettingsChangedState(ACodec *codec);
288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
289f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual PortMode getPortMode(OMX_U32 portIndex);
291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
296f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
302f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::ExecutingToIdleState : public ACodec::BaseState {
303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ExecutingToIdleState(ACodec *codec);
304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
305f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
314f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool mComponentNowIdle;
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
322f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
324f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::IdleToLoadedState : public ACodec::BaseState {
325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IdleToLoadedState(ACodec *codec);
326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
327f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
333f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
339f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstruct ACodec::FlushingState : public ACodec::BaseState {
340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    FlushingState(ACodec *codec);
341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
342f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprotected:
343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onMessageReceived(const sp<AMessage> &msg);
344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void stateEntered();
345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onOutputBufferDrained(const sp<AMessage> &msg);
349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    virtual void onInputBufferFilled(const sp<AMessage> &msg);
350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberprivate:
352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool mFlushComplete[2];
353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    void changeStateIfWeOwnAllBuffers();
355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber};
358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
361f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ACodec()
362afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    : mQuirks(0),
363afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber      mNode(NULL),
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSentFormat(false),
365c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber      mIsEncoder(false),
366308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      mUseMetadataOnEncoderOutput(false),
3679806555d3930be43e11106281dee354820ac1c88Andreas Huber      mShutdownInProgress(false),
3689806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
374a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37594ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerCaptureUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
381c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
394dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
399f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
402f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
406f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4385778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
442f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4437a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
447f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
451c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
457496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
473f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
481054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
507ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
510afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
515308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
516308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
524308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
525308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5381065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5401065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
552eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
556eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
558eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
561eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
567054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
568054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5943c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5975ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5983c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
5993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6003c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6013c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
602bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6273c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
634054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
635258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
637054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
638258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
64029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
641258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
645e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
646e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
6471faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
6481faa41704e0b976e546321effcb09a85767d51baLajos Molnar    // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
649e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
650e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
651e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
652e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
653e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
654e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
655e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
6561faa41704e0b976e546321effcb09a85767d51baLajos Molnar    //    plus an extra buffer to account for incorrect minUndequeuedBufs
6571faa41704e0b976e546321effcb09a85767d51baLajos Molnar    for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
658e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        OMX_U32 newBufferCount =
659e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
660258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        def.nBufferCountActual = newBufferCount;
661258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        err = mOMX->setParameter(
662258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
663258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
664e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (err == OK) {
665e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            *minUndequeuedBuffers += extraBuffers;
666e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar            break;
667e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        }
668e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
669e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        ALOGW("[%s] setting nBufferCountActual to %lu failed: %d",
670e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar                mComponentName.c_str(), newBufferCount, err);
671e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        /* exit condition */
672e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar        if (extraBuffers == 0) {
673258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            return err;
674258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        }
675258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
676258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffer_count(
678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(), def.nBufferCountActual);
679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
68129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                -err);
683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
686054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferCount = def.nBufferCountActual;
687054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *bufferSize =  def.nBufferSize;
688054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
689054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
690054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
691054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputBuffersFromNativeWindow() {
692054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
693054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
694054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
695054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
696054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
697e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
698054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
6993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         "output port",
701054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount, bufferSize);
702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Dequeue buffers and send them to OMX
704054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
7058ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev        ANativeWindowBuffer *buf;
7061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
70829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
71374006804065941841883c4b46ee785070164023fJamie Gennis        BufferInfo info;
71474006804065941841883c4b46ee785070164023fJamie Gennis        info.mStatus = BufferInfo::OWNED_BY_US;
715054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
71674006804065941841883c4b46ee785070164023fJamie Gennis        info.mGraphicBuffer = graphicBuffer;
71774006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].push(info);
71874006804065941841883c4b46ee785070164023fJamie Gennis
719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferId;
720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &bufferId);
722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != 0) {
72329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
72474006804065941841883c4b46ee785070164023fJamie Gennis                 "%d", i, err);
725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
72874006804065941841883c4b46ee785070164023fJamie Gennis        mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
72974006804065941841883c4b46ee785070164023fJamie Gennis
7303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mComponentName.c_str(),
732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             bufferId, graphicBuffer.get());
733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelStart;
736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 cancelEnd;
737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // If an error occurred while dequeuing we need to cancel any buffers
740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // that were dequeued.
741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelStart = 0;
74274006804065941841883c4b46ee785070164023fJamie Gennis        cancelEnd = mBuffers[kPortIndexOutput].size();
743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
744054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // Return the required minimum undequeued buffers to the native window.
745054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelStart = bufferCount - minUndequeuedBuffers;
746054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        cancelEnd = bufferCount;
747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        cancelBufferToNativeWindow(info);
752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
757054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::allocateOutputMetaDataBuffers() {
758054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
759054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    status_t err = configureOutputBuffersFromNativeWindow(
760054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            &bufferCount, &bufferSize, &minUndequeuedBuffers);
761054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (err != 0)
762054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return err;
763e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    mNumUndequeuedBuffers = minUndequeuedBuffers;
764054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
765054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] Allocating %lu meta buffers on output port",
766054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar         mComponentName.c_str(), bufferCount);
767054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
768054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    size_t totalSize = bufferCount * 8;
769054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
770054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
771054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Dequeue buffers and send them to OMX
772054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (OMX_U32 i = 0; i < bufferCount; i++) {
773054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo info;
774054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
775054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mGraphicBuffer = NULL;
776054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mDequeuedAt = mDequeueCounter;
777054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
778054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
779054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                sizeof(struct VideoDecoderOutputMetaData));
780054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mem.get() != NULL);
781054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        info.mData = new ABuffer(mem->pointer(), mem->size());
782054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
783054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // we use useBuffer for metadata regardless of quirks
784054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->useBuffer(
785054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mNode, kPortIndexOutput, mem, &info.mBufferID);
786054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
787054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        mBuffers[kPortIndexOutput].push(info);
788054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
789054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
790054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mComponentName.c_str(), info.mBufferID, mem->pointer());
791054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
792054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
793054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
794054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return err;
795054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
796054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
797054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::submitOutputMetaDataBuffer() {
798054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mStoreMetaDataInOutputBuffers);
799054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mMetaDataBuffersToSubmit == 0)
800054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return OK;
801054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
802054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *info = dequeueBufferFromNativeWindow();
803054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (info == NULL)
804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return ERROR_IO;
805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
806054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
807054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar          mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
809054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    --mMetaDataBuffersToSubmit;
810054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
811054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             (status_t)OK);
812054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
813054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
814054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    return OK;
815054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
816054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
817f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
8203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Calling cancelBuffer on buffer %p",
821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mComponentName.c_str(), info->mBufferID);
822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int err = mNativeWindow->cancelBuffer(
8241e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, 0);
827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
833f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::dequeueBufferFromNativeWindow() {
8348ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
8351e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    int fenceFd = -1;
836054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    CHECK(mNativeWindow.get() != NULL);
8371e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
83829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("dequeueBuffer failed.");
839c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber        return NULL;
840c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
841f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
842054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    BufferInfo *oldest = NULL;
843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
847054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mGraphicBuffer != NULL &&
848054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            info->mGraphicBuffer->handle == buf->handle) {
849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus,
850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
856054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
857054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
858054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (oldest == NULL ||
859054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             // avoid potential issues from counter rolling over
860054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar             mDequeueCounter - info->mDequeuedAt >
861054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    mDequeueCounter - oldest->mDequeuedAt)) {
862054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            oldest = info;
863054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
864054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
865054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
866054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (oldest) {
867054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        CHECK(mStoreMetaDataInOutputBuffers);
868054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
869054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        // discard buffer in LRU info and replace with new buffer
870054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
871054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        oldest->mStatus = BufferInfo::OWNED_BY_US;
872054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
873d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        mOMX->updateGraphicBufferInMeta(
874d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                mNode, kPortIndexOutput, oldest->mGraphicBuffer,
875d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mBufferID);
876054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
877d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        VideoDecoderOutputMetaData *metaData =
878d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar            reinterpret_cast<VideoDecoderOutputMetaData *>(
879d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                    oldest->mData->base());
880d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
881d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar
882d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar        ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
883054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                oldest - &mBuffers[kPortIndexOutput][0],
884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mDequeueCounter - oldest->mDequeuedAt,
885d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                metaData->pHandle,
886d0715867861c216e88a4a7523b6da8a3cb128724Lajos Molnar                oldest->mGraphicBuffer->handle, oldest->mData->base());
887054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
888054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        return oldest;
889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
896f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffersOnPort(OMX_U32 portIndex) {
897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
901f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDealer[portIndex].clear();
902f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
905f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
906349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huberstatus_t ACodec::freeOutputBuffersNotOwnedByComponent() {
907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info =
909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &mBuffers[kPortIndexOutput].editItemAt(i);
910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9112ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // At this time some buffers may still be with the component
9122ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        // or being drained.
9132ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar        if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
9142ded8b53014602d25b20bade8ce46db95a8da4b5Lajos Molnar            info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
918f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
919f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
920f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
921f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
922f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::freeBuffer(OMX_U32 portIndex, size_t i) {
923f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
924f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
925f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(info->mStatus == BufferInfo::OWNED_BY_US
926f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
927f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
928f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput && mNativeWindow != NULL
929f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && info->mStatus == BufferInfo::OWNED_BY_US) {
930f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
931f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
932f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
933f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(mOMX->freeBuffer(
934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, portIndex, info->mBufferID),
935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mBuffers[portIndex].removeAt(i);
938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
941f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
942f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BufferInfo *ACodec::findBufferByID(
943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        uint32_t portIndex, IOMX::buffer_id bufferID,
944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ssize_t *index) {
945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
947f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mBufferID == bufferID) {
949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (index != NULL) {
950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                *index = i;
951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return info;
953f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    TRESPASS();
957f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
958f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return NULL;
959f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
960f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setComponentRole(
962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        bool isEncoder, const char *mime) {
963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    struct MimeToRole {
964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime;
965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *decoderRole;
966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *encoderRole;
967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
968f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
969f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const MimeToRole kMimeToRole[] = {
970f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG,
971f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.mp3", "audio_encoder.mp3" },
9722944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
9732944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp1", "audio_encoder.mp1" },
9742944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
9752944eca607304a095ea43ba2b8f0b9de61249f9fAndreas Huber            "audio_decoder.mp2", "audio_encoder.mp2" },
976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrnb", "audio_encoder.amrnb" },
978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
979f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.amrwb", "audio_encoder.amrwb" },
980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_AUDIO_AAC,
981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "audio_decoder.aac", "audio_encoder.aac" },
982729de186450f78c099637e1fce743fe531862c52Andreas Huber        { MEDIA_MIMETYPE_AUDIO_VORBIS,
983729de186450f78c099637e1fce743fe531862c52Andreas Huber            "audio_decoder.vorbis", "audio_encoder.vorbis" },
984bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian        { MEDIA_MIMETYPE_AUDIO_OPUS,
985bf927f8ec7979f2b64331c2b2f12a6a5dba05bcaVignesh Venkatasubramanian            "audio_decoder.opus", "audio_encoder.opus" },
986c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
987c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
988c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
989c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber            "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_AVC,
991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.avc", "video_encoder.avc" },
992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_MPEG4,
993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.mpeg4", "video_encoder.mpeg4" },
994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        { MEDIA_MIMETYPE_VIDEO_H263,
995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            "video_decoder.h263", "video_encoder.h263" },
99694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP8,
99794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp8", "video_encoder.vp8" },
99894705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang        { MEDIA_MIMETYPE_VIDEO_VP9,
99994705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang            "video_decoder.vp9", "video_encoder.vp9" },
1000ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        { MEDIA_MIMETYPE_AUDIO_RAW,
1001ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            "audio_decoder.raw", "audio_encoder.raw" },
10022f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        { MEDIA_MIMETYPE_AUDIO_FLAC,
10032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            "audio_decoder.flac", "audio_encoder.flac" },
1004ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen        { MEDIA_MIMETYPE_AUDIO_MSGSM,
1005ba933df89521d63f75ca66af12ce9d7ae9496b9eMarco Nelissen            "audio_decoder.gsm", "audio_encoder.gsm" },
1006774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu        { MEDIA_MIMETYPE_VIDEO_MPEG2,
1007774eb18c40c3a7da0bc1636a9779f02315ddbad8Changwan Ryu            "video_decoder.mpeg2", "video_encoder.mpeg2" },
100897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        { MEDIA_MIMETYPE_AUDIO_AC3,
100997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            "audio_decoder.ac3", "audio_encoder.ac3" },
1010f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    };
1011f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1012f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    static const size_t kNumMimeToRole =
1013f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
1014f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1015f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    size_t i;
1016f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (i = 0; i < kNumMimeToRole; ++i) {
1017f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
1018f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1019f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1020f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1021f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1022f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (i == kNumMimeToRole) {
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return ERROR_UNSUPPORTED;
1024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    const char *role =
1027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        isEncoder ? kMimeToRole[i].encoderRole
1028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                  : kMimeToRole[i].decoderRole;
1029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (role != NULL) {
1031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_PARAM_COMPONENTROLETYPE roleParams;
1032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        InitOMXParams(&roleParams);
1033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        strncpy((char *)roleParams.cRole,
1035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                role, OMX_MAX_STRINGNAME_SIZE - 1);
1036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
1038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->setParameter(
1040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamStandardComponentRole,
1041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &roleParams, sizeof(roleParams));
1042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
10445ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("[%s] Failed to set standard component role '%s'.",
1045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 mComponentName.c_str(), role);
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
1048f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::configureCodec(
1055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const char *mime, const sp<AMessage> &msg) {
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t encoder;
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("encoder", &encoder)) {
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        encoder = false;
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1061e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> inputFormat = new AMessage();
1062e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> outputFormat = new AMessage();
1063e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1083d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1084d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1088d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1089308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1091308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1092d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1093308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
11003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
11013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
11023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11173a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11183a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11193a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1120308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1121308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1122308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1125308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1126308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1127308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1128308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1129308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1132308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1133308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1134308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1135308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1136308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1137308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1141a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1142a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1143a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
114494ee4b708acfa941581160b267afb79192b1d816Chong Zhang
114594ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11482c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11492c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11502c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
115194ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
115272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
115372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
115472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
115572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
115672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
115772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1158308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1159308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1162054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
1165e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (video && !encoder) {
1166e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        inputFormat->setInt32("adaptive-playback", false);
1167e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1168054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1169054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1170054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1171054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1172054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1187fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1188fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1190fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1191fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1192fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1193fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1194fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1195fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1196fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1197fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1199fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
120484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1205fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1207fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1210fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1211fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
1212e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1213e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                if (err == OK) {
1214e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-width", maxWidth);
1215e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("max-height", maxHeight);
1216e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    inputFormat->setInt32("adaptive-playback", true);
1217e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
1218fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1219fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1220054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1221054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1222054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1223054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
1224e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            inputFormat->setInt32("adaptive-playback", true);
1225054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12260167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12270167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12280167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12290167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12300167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12310167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1232054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1233054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1234308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
124642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
124742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
124842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
124942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
125042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
125142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
125242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
125342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
125442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
125542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
125642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
125742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
125842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1265aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1266ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1267ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1268ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1269aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1270aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1271aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1272ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1273ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12744471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12754471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1277729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1279729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1281729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1282729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1283729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1284729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1285729de186450f78c099637e1fce743fe531862c52Andreas Huber
1286729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12922f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12952f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12962f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12972f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
13002f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1301516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1302516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
13032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
13042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1305516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1306516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1307516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
13092f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1310516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1311516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1312516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13132f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13142f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13152f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1316516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1317516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13182f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1319ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1320ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1321ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1322ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1323ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1324ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1325ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1326ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1327ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
132897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
132997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
133097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
133197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
133297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
133397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
133497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
133597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
133697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1338729de186450f78c099637e1fce743fe531862c52Andreas Huber
13394471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13404471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13414471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13424471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13438b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13448b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13458b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13469806555d3930be43e11106281dee354820ac1c88Andreas Huber
13478b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13519806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13529806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13539806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13549806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13559806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13569806555d3930be43e11106281dee354820ac1c88Andreas Huber
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1364e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexInput, inputFormat), (status_t)OK);
1365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, outputFormat), (status_t)OK);
1366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mInputFormat = inputFormat;
1367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mOutputFormat = outputFormat;
1368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1407f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1436aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1437aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1438ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1439ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1440ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1441ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1502aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1523f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1524f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1525f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1528ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1530ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1532ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
153897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
153997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
154097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
154197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
154297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
154497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
154597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
154697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
154897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
154997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
155097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
155197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
155397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
155497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
155597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
155797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
155897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
155997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
156097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
156197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
156397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
156497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
156597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
156797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
156897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
156997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
157097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
157197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
157297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
157397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
157497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
157597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1622729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1623729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1625729de186450f78c099637e1fce743fe531862c52Andreas Huber
1626729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1627729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1628729de186450f78c099637e1fce743fe531862c52Andreas Huber
1629729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1630729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1631729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1642729de186450f78c099637e1fce743fe531862c52Andreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1647729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1648729de186450f78c099637e1fce743fe531862c52Andreas Huber
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1652729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1653729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1654729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1655729de186450f78c099637e1fce743fe531862c52Andreas Huber
16562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16692f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16732f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16742f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16752f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16762f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16772f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16782f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16792f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16802f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16812f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1684729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1685729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber
1690729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1691729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1692729de186450f78c099637e1fce743fe531862c52Andreas Huber
1693729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1694729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1695729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1696729de186450f78c099637e1fce743fe531862c52Andreas Huber
1697729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1698729de186450f78c099637e1fce743fe531862c52Andreas Huber
1699729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1700729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1701729de186450f78c099637e1fce743fe531862c52Andreas Huber
1702729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1703729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1704729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1705729de186450f78c099637e1fce743fe531862c52Andreas Huber
1706729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1707729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1708729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1709729de186450f78c099637e1fce743fe531862c52Andreas Huber
1710729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1711729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1712729de186450f78c099637e1fce743fe531862c52Andreas Huber
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1714729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1716729de186450f78c099637e1fce743fe531862c52Andreas Huber
1717729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1718729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1719729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1720729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1721729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1722729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1723729de186450f78c099637e1fce743fe531862c52Andreas Huber
1724c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1725c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1726729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1727729de186450f78c099637e1fce743fe531862c52Andreas Huber
1728729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1729729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1730729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1731729de186450f78c099637e1fce743fe531862c52Andreas Huber
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
181694705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
181794705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1888f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1890f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
203489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
203589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
203689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
203789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
203889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20760dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20770dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20780dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20790dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
209696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
209796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
209896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
209996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
210096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
210196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
210296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
210396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
210496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
211296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
211396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
217796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
219396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
219496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
226996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
227096076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22810dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22820dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22830dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22840dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22850dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22860dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22870dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22880dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22890dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22900dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22950dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23237c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23247c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23257c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
236796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
237089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
237189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
237289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
237389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
237489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
237589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
237689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
237789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
237889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
237989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
238089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
240896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
242196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2491f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2500d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2501d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2502d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2503d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2504d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2505d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2506d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2507d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2508d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2509d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2510d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2511d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2512d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2513d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
25147e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
25157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
25167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
25187e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
25197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25207e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25217e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
25227e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
25237e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
25267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25277e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25287e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
25297e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
25307e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
25317e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25327e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2533e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
25347e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2535c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2536c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2537c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2538c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
25397e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25407e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25417e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2564f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2569f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2579e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
2580e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    // TODO: catch errors an return them instead of using CHECK
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
258231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
2583e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    def.nPortIndex = portIndex;
258431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
258531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
258631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
258731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
258831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2589e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ((int)def.eDir,
2590e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            (int)(portIndex == kPortIndexOutput ? OMX_DirOutput : OMX_DirInput));
259131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
259231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
259331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
259431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
259531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
2596e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            switch ((int)videoDef->eCompressionFormat) {
2597e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_VIDEO_CodingUnused:
2598e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2599e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexOutput));
2600e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2601e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2602e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("stride", videoDef->nStride);
2603e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("slice-height", videoDef->nSliceHeight);
2604e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("color-format", videoDef->eColorFormat);
2605e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2606e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_CONFIG_RECTTYPE rect;
2607e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&rect);
2608e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    rect.nPortIndex = kPortIndexOutput;
2609e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2610e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (mOMX->getConfig(
2611e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexConfigCommonOutputCrop,
2612e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &rect, sizeof(rect)) != OK) {
2613e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nLeft = 0;
2614e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nTop = 0;
2615e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nWidth = videoDef->nFrameWidth;
2616e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        rect.nHeight = videoDef->nFrameHeight;
2617e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
261831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2619e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nLeft, 0);
2620e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nTop, 0);
2621e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nWidth, 0u);
2622e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_GE(rect.nHeight, 0u);
2623e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2624e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2626e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setRect(
2627577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2628577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2629577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2630e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nLeft + rect.nWidth - 1,
2631e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                            rect.nTop + rect.nHeight - 1);
2632e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2633e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2634e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2635e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                default:
2636e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2637e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(mIsEncoder ^ (portIndex == kPortIndexInput));
2638e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    AString mime;
2639e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    if (GetMimeTypeForVideoCoding(
2640e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        videoDef->eCompressionFormat, &mime) != OK) {
2641e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", "application/octet-stream");
2642e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    } else {
2643e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                        notify->setString("mime", mime.c_str());
2644e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    }
2645e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
264731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
2648e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2649e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("width", videoDef->nFrameWidth);
2650e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            notify->setInt32("height", videoDef->nFrameHeight);
265131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
265231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
265331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
265431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
265531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
265631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
265731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
265897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2659e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2660e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2661e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2662e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2663e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2664e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
267014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
267314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
267414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
267514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
267614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
267714f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
267814f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2679e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2681e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2683e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2684e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mChannelMaskPresent) {
2685e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("channel-mask", mChannelMask);
26868b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                    }
2687e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
26888b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                }
26899806555d3930be43e11106281dee354820ac1c88Andreas Huber
2690e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAAC:
2691e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2692e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AACPROFILETYPE params;
2693e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2694e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2695e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2696e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2697e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAac,
2698e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2699e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2700e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2701e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingAMR:
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_AMRTYPE params;
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2711e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
27129806555d3930be43e11106281dee354820ac1c88Andreas Huber
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioAmr,
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", 1);
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (params.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0) {
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 16000);
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setString(
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                "mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        notify->setInt32("sample-rate", 8000);
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingFLAC:
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_FLACTYPE params;
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2737e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioFlac,
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_FLAC);
2745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSampleRate);
2747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    break;
2748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2750e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingMP3:
2751e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2752e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_MP3TYPE params;
2753e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2754e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2755e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2756e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2757e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioMp3,
2758e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2759e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2760e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2761e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_MPEG);
2762e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2763e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2764e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2765e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2766e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2767e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                case OMX_AUDIO_CodingVORBIS:
2768e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                {
2769e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    OMX_AUDIO_PARAM_VORBISTYPE params;
2770e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    InitOMXParams(&params);
2771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
2772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK_EQ(mOMX->getParameter(
2774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                mNode, OMX_IndexParamAudioVorbis,
2775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                                &params, sizeof(params)),
2776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                             (status_t)OK);
2777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_VORBIS);
2779e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("channel-count", params.nChannels);
2780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    notify->setInt32("sample-rate", params.nSampleRate);
2781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    break;
2782e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                }
2783e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
278497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
278597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
278697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
278797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
2788e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    params.nPortIndex = portIndex;
278997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
279097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
279197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
279297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
279397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
279497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
279597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
279697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
279797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
279897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
279997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
280097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    ALOGE("UNKNOWN AUDIO CODING: %d\n", audioDef->eEncoding);
2804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
280631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
280731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
280831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
280931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
281031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
281131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
281231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
2814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
2815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
2817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> notify = mNotify->dup();
2818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    notify->setInt32("what", kWhatOutputFormatChanged);
2819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK_EQ(getPortFormat(kPortIndexOutput, notify), (status_t)OK);
2821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    AString mime;
2823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(notify->findString("mime", &mime));
2824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
2825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    int32_t left, top, right, bottom;
2826e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if (mime == MEDIA_MIMETYPE_VIDEO_RAW &&
2827e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mNativeWindow != NULL &&
2828e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->findRect("crop", &left, &top, &right, &bottom)) {
2829e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // notify renderer of the crop change
2830e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        // NOTE: native window uses extended right-bottom coordinate
2831e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        reply->setRect("crop", left, top, right + 1, bottom + 1);
2832e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    } else if (mime == MEDIA_MIMETYPE_AUDIO_RAW &&
2833e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar               (mEncoderDelay || mEncoderPadding)) {
2834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        int32_t channelCount;
2835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        CHECK(notify->findInt32("channel-count", &channelCount));
2836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        size_t frameSize = channelCount * sizeof(int16_t);
2837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        if (mSkipCutBuffer != NULL) {
2838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            size_t prevbufsize = mSkipCutBuffer->size();
2839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (prevbufsize != 0) {
2840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                ALOGW("Replacing SkipCutBuffer holding %d "
2841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      "bytes",
2842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                      prevbufsize);
2843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            }
2844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        }
2845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        mSkipCutBuffer = new SkipCutBuffer(
2846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderDelay * frameSize,
2847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                mEncoderPadding * frameSize);
2848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
2849e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
285031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
285131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
285231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
285331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
285431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
28555778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2856cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2857cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2858cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
28595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2860cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2861cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2862cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2890bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2891bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
289687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
289787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
289887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
289987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
290087eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
290187eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2905bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2922bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2923bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2924bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2925bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2926bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2927bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2928bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2929bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2930bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2931bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2932bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
29331e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
29341e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2935bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2936bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2937bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2938bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2939bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2940bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2941bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2942bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2943bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2944bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2945bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2946bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2947bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2948bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2949bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2950bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2951bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2952bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2953bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2954bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2955bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2956bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2957bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2958bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2959bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2960bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2961bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
29621e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2963bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2964bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2965bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2966bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2967bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2968bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2969bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2970bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2971bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2972bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2973bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2974bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2975bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2976bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
29771e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2978bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2979bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2980bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2981bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2982bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2983bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2984bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2985bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2986bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2987bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2988bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2989bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2990bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2991bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2992bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2993bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2994bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2995bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2996bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2997bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2998bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2999bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
3000bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
3001bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
3002bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
3003bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3004bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
3005bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
3006bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
3007bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
3008f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3009f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3010eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
3011eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3012eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3013496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
3014496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
3015496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
3016496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
3017496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3018496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
3019496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
3020496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3021496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
3022496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
3023496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3024496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
3025496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
3026496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
3027496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
3028496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
3029496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
3030496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
3031eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
3032eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
3033eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
3034eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
3035eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3036eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3037eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
3038eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
3039eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3040eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3041eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
3042eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
3043eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3044eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3045eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
3046eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
3047eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
3048eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3049eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
3050eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
3051f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
3052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
3053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
3054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3056ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
3057ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
30817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
30827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
30837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
30847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
30857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
30867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
30877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3088ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3089ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3090ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3091ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3092ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3093ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3094ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31065e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // there is a possibility that this is an outstanding message for a
31075e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    // codec that we have already destroyed
31085e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    if (mCodec->mNode == NULL) {
31095e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        ALOGI("ignoring message as already freed component: %s",
31105e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar                msg->debugString().c_str());
31115e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar        return true;
31125e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar    }
31135e184b0d12f1ec436246a391da8d9355cc21ee08Lajos Molnar
3114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3120f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31260af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
31270af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
31280af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
31290af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
31300af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
31310af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
31320af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
31330af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
31340af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
31350af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
31360af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3146f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
31863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
319229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3194cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3199f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
32003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3201349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3202349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3207f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3208f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3209d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3210d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3211d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3212d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3213d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3214d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3215d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3216d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3217d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
321896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
321996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
322096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3221d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3222d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3223d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3224d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3225d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3226d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
32602d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3268f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3272f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3274f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32762d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
32785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3279a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
32805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32812d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3282a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32857fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
32867fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
32877fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
32887fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
32897fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
32907fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
32917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
32927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
32933831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
32942d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
32985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
32995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
33005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
33015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
33025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3312dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3313dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3314dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3315dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3323f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3325f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3326f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3327f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3328f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3329f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3330f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3331f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3332f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
33345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
33355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
33365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3338d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3339d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3340d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3341d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3347078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
33483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3349078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
33505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
33515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
33525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3353078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3354d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3355d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3356d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3357d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
33583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3359078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3360d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3361078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3362349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3363d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3364d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3365d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3366d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3367d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3368d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3369d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3370054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3371054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3375054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3376054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3377054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3378054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3379054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3380054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3381054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3382054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3383054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
33985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
33995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
34005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
34025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
34035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3405dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
34063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3407dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3408dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3409dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
34103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3411dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3412dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3413f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3415349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3416349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3421f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3429dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3432f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3433625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3434625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3435625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3436625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3437f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3438f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3440f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3469f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3474ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* platformPrivate */,
3475ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* dataPtr */) {
34765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3478349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3480d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3481d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3482d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3483d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3484d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3485d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3486d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3487d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3488d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3489d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3490d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3491d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3492d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3493d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3494d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3495d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3501054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
35125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
35135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
35145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3515349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
35165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
35175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
35185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
35215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
35225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
352331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3524577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3525577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3526577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
35274bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3528577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
35295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3531308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3532308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3533308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3534308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3535308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3536308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3537308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3538308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3539308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3540496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
354121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3542496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3543496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3544496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
35455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
354621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35488b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
35498b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
35508b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
35515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
35545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
35555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
35562d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
35575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
35645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
35685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
35695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3572dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3602577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3603577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3604577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3605577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3606577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3607577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3608577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
36116aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
361279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
36165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
36181e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3619cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3620cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
36215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3622cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3623cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3645f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3646f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3654c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
36553856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3656c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3657349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3658c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3659c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3661c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3662c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3675f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3676f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3680f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3684c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3685c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3686ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3687ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3688ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3689ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3690ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3691ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3692ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3693ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3694ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3695ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3696ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3697308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3698ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3699c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3700c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3732c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3742c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3752f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3754c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3755c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3756c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3757c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
37585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
37615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
37625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3763c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
37645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3770ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3771ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3772ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3773ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3774ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3775ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3776ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3777ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3778ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3779e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3784d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
37855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3786e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3787e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3788e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3789afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3790e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3791e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3792e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3793afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
37945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
37955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
37965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
37985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
37995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
38005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
38015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
38035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
38045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
38055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
38065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3807e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
38085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
38091065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38101065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
38111065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
38121065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38131065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
38141065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3815e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3816e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3818078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3819078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3820078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
38211065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3822078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38241065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
38251065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
38261065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
38271065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
38281065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
38291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
38301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3831c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
38325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
38335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
38345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
38355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
38365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
38375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3838c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3839cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3841c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3843ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3847ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3848ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3849ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3850ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
38510167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3852ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3853ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3854afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
38585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
38595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
38605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
38615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
38625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
38635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3866c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3867c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
38685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
38695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3870c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3871c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3872c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3875c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3876c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3877c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3878c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3879f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3880f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3881f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3882f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3883f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3884054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3885054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3886a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
3887e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mInputFormat.clear();
3888e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    mCodec->mOutputFormat.clear();
3889054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3890c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3891c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3892c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3893c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3894c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3895c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3896c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3897c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3898c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3899c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3900c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3901c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3902c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3903c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3904c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3905c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3906c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3907c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3910c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3911c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3912c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3913c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3914c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3915c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3916c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3917c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3918c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3919c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3920c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3921c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3922c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
39237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
39247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
39257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
39267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
39277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
39287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
39297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3930c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3931c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3933c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3934c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3935c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3936c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3937c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3938c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3939c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3941c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3942c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3943c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3944c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3945c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3946c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3947c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3948c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3949c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3950c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3951c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3952c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3953c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3954c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3955c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3956c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3957c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3958c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3959c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3960c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3961c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3962c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3963c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3964c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3965c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3966c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
39675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
39685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
39695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
39715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
39735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
39745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
39765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3978c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3979c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3980c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
39815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3982c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
39835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3984f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3985f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3986386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
39875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
39881173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
39891173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
39901173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
39911173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
39921ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
39931ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
39941ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
39951ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
40005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
40015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
4002e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("input-format", mCodec->mInputFormat);
4003e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        notify->setMessage("output-format", mCodec->mOutputFormat);
40045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
40055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4006c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4007c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
40085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
40095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
4011ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
40127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
40137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
40157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
40167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
40187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
40197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
40207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
40217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
4022a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4023a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
4024a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
4025a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
4026a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
4027a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
4028a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
4029a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
4030a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
4031a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
4032a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
4033a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
4034a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
4035a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
4036a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
4037a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
4038a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
40392c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
404094ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
404194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
404294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
404394ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
404494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
404594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
404694ee4b708acfa941581160b267afb79192b1d816Chong Zhang
404794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
404894ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
404972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
405072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
40512c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
40522c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
40532c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
40542c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
40552c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
40562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
40572c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
40582c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
40592c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
40602c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
40612c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
40622c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
40632c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
40642c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
40652c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
40662c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
40672c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
40682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
40692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
40702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
40712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
407272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
407372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
407472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
407572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
407672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
407772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
407872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
407972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
408072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
408172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
408272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
408372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
408494ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
408594ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
408694ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
408794ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
408894ee4b708acfa941581160b267afb79192b1d816Chong Zhang
40897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
40907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
40917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
40927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
40937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
40947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
40957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
40967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
40977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
40987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
40997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
41007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
41017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
41027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
41045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
41055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
41075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4115f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
41203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4122cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4123cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
412429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4125cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4126cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4127cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
41285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
412991bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
413091bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4131cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4137f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4138f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4139f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4140f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4144f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4145f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
414672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
41536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
41546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
41556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
41576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
41586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
41596463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
41606463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
41616463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
41626463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
41636463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
41646463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
41656463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
41666463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
41676463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
41686463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
41696463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
41706463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
41716463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
41726463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
41736463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4199f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4200f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4201f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4202f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4203f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4205f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4206f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4207f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
42083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4209f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4210f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4211f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
421372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4220d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4221d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4222d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4223d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4224d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4225d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4226d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4227d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4228d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4229d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4230d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4231d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4232d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4233d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4234d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4235d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
42366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
42376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
42386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
42396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
42406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
42416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4242f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4247f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4258f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4259f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4268f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4269349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4270349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4273f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4274ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4275f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4276f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4277f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4278054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4279054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4280054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4281054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4282054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4283054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4284054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4285054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4286054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4287054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4288054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
42894dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
42904dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42914dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4292054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4293054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4294054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4295f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4296f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4297f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4298f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4299f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4300f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4301f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4302f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4303f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
43093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4310349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4311349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4319054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4320c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4321054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4322054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4323054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4324054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4325054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4326f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4327349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
43283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4329349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4330349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4331349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4332349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4333349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4334f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4335f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4336f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4341349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4342349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4345f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
43463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4349f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4351f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4353f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4354f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4357c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4358c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4359c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4360c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4361c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4364349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4365349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
43787a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4379d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4380d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4381d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4382d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4383d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4384d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4385d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4386349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4387349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4395f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4400f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4403f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4405496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4406496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4407496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4408496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4409496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4410496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4412496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4413496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4414496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4415496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4419a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4420a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4421a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4422a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4423a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4424a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4425a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4426a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4427a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4428a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4429a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4430a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4431a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4432a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
44337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
44347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
44356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
44367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
44377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
44387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
44397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
44404dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
44414dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
44424dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
44434dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
44444dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
44454dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
44464dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
44474dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
44484dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
44494dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
44504dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
44514dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
44524dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4461a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4462a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4463530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4464a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4465a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4466a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4467a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4468a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4469a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4470a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4471a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4472a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4473a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4474a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4475a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4476a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4477a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4478a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4479a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4480a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4481a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4482a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
448372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
448472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
448572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
448672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
448772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
448872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
448972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
449072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
449172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
449272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
449372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
449472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
449572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
449672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
449772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
449872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4499e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4500e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4501e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4502e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4503b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4504b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4505e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4506e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4507e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4508e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4509b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4510b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4511b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4512b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4513b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4514b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4515b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4516b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4517b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4518b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4519b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4520b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4521b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4522b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4523b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4524b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4525e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4526e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4527a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4528a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4529a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
45306507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
45316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
45326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
45336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
45346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
45356507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
45366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
45376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
45386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
45396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
45406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
454831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4549054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
455831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
455931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
45613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4580f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4585f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4603349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4605349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
46063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4607349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4608349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4609f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4610f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4611f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
46233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4643f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4644f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4645cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4646cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4647cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
464829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4649cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4650cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4651cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
46525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4653d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4654755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4655755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4656755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4657755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4658755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4659755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4660755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4661755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4662cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
466831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
466931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
46703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4673349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4674349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4675349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4676349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4677f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4690f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4691f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4692f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
46935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
46945778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4714f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
47263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
472731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
47285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
472931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
47415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4747349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4748349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4749349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4750349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4751349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4752349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4753349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
47580af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
47605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
47680167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
47690167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4770bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4771bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4772bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4773bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4774bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4775bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4776bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4807f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4808f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4809f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4818f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4819f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4820f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4821f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4822f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
48303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4834f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4835f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4836f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4837f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4838f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4839f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4840f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4842f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4843f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4844f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4845f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4846f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4853f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
48583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4876f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4877f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4886f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4887f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4888f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4889f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
48907a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4891d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4892d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4896f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4897f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4898f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4899f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4900f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4901e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4902e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4903e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4904e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4905e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4906f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4907f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4908f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4909f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4910f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4911f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4912f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4913f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4914f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4917349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4918349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4919349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4920349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4921349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4922349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4923349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4924349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4925349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
49263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4927349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4928349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4929349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4930349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4931349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4932349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4933349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4934f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4935f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4938f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4939f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4940f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4941f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4942f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4943f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4944f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4945f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4946f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4947f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4948f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4949f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4950f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4951f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4952f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4953f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4954f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4955f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4956f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
49577e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
49587e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
49597e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
49607e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4961f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4962f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4963f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4964f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4965f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4966f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4967f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4968dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4969dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4970f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4971f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4972f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4973f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4974f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4975f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4976f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4977f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4978f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4979