ACodec.cpp revision e257e5ebefdd50f808ee3b4d1596db261c9b62dd
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),
36875832930a28fd70f6fc683ed966477ceea810668Robert Shih      mIsConfiguredForAdaptivePlayback(false),
3699806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderDelay(0),
3709806555d3930be43e11106281dee354820ac1c88Andreas Huber      mEncoderPadding(0),
3719806555d3930be43e11106281dee354820ac1c88Andreas Huber      mChannelMaskPresent(false),
372054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mChannelMask(0),
373054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mDequeueCounter(0),
374054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar      mStoreMetaDataInOutputBuffers(false),
375a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber      mMetaDataBuffersToSubmit(0),
37694ee4b708acfa941581160b267afb79192b1d816Chong Zhang      mRepeatFrameDelayUs(-1ll),
3772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mMaxPtsGapUs(-1ll),
3782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerCaptureUs(-1ll),
3792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang      mTimePerFrameUs(-1ll),
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mCreateInputBuffersSuspended(false) {
381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mUninitializedState = new UninitializedState(this);
382c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mLoadedState = new LoadedState(this);
383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mLoadedToIdleState = new LoadedToIdleState(this);
384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToExecutingState = new IdleToExecutingState(this);
385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingState = new ExecutingState(this);
386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOutputPortSettingsChangedState =
388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        new OutputPortSettingsChangedState(this);
389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mExecutingToIdleState = new ExecutingToIdleState(this);
391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mIdleToLoadedState = new IdleToLoadedState(this);
392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushingState = new FlushingState(this);
393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
394f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
395dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber    mInputEOSResult = OK;
396f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
397f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeState(mUninitializedState);
398f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
400f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::~ACodec() {
401f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
402f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
403f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::setNotificationMessage(const sp<AMessage> &msg) {
404f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mNotify = msg;
405f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
406f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
407f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::initiateSetup(const sp<AMessage> &msg) {
408f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setWhat(kWhatSetup);
409f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->setTarget(id());
410f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    msg->post();
411f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
412f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Hubervoid ACodec::signalSetParameters(const sp<AMessage> &params) {
414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->post();
417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateAllocateComponent(const sp<AMessage> &msg) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatAllocateComponent);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateConfigureComponent(const sp<AMessage> &msg) {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setWhat(kWhatConfigureComponent);
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setTarget(id());
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->post();
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::initiateCreateInputSurface() {
4327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatCreateInputSurface, id()))->post();
4337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::signalEndOfInputStream() {
4367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    (new AMessage(kWhatSignalEndOfInputStream, id()))->post();
4377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4395778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::initiateStart() {
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    (new AMessage(kWhatStart, id()))->post();
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
443f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalFlush() {
4447a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] signalFlush", mComponentName.c_str());
445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatFlush, id()))->post();
446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
448f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::signalResume() {
449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    (new AMessage(kWhatResume, id()))->post();
450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
452c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::initiateShutdown(bool keepComponentAllocated) {
453c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatShutdown, id());
454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->setInt32("keepComponentAllocated", keepComponentAllocated);
455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    msg->post();
456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Hubervoid ACodec::signalRequestIDRFrame() {
459496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
461496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
4634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// Some codecs may return input buffers before having them processed.
4644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// This causes a halt if we already signaled an EOS on the input
4654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// port.  For now keep submitting an output buffer if there was an
4664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar// EOS on the input port, but not yet on the output port.
4674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnarvoid ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
4684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
4694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            mMetaDataBuffersToSubmit > 0) {
4704dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
4714dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    }
4724dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar}
4734dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
474f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
476f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mDealer[portIndex] == NULL);
478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(mBuffers[portIndex].isEmpty());
479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
482054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (mStoreMetaDataInOutputBuffers) {
483054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputMetaDataBuffers();
484054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
485054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = allocateOutputBuffersFromNativeWindow();
486054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = portIndex;
491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err == OK) {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mComponentName.c_str(),
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    def.nBufferCountActual, def.nBufferSize,
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    portIndex == kPortIndexInput ? "input" : "output");
500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            size_t totalSize = def.nBufferCountActual * def.nBufferSize;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(mem.get() != NULL);
507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
508ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                BufferInfo info;
509ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                info.mStatus = BufferInfo::OWNED_BY_US;
510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
511afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                uint32_t requiresAllocateBufferBit =
512afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                    (portIndex == kPortIndexInput)
513afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        ? OMXCodec::kRequiresAllocateBufferOnInputPorts
514afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber                        : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
5151065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
516308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                if ((portIndex == kPortIndexInput && (mFlags & kFlagIsSecure))
517308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        || mUseMetadataOnEncoderOutput) {
518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    mem.clear();
519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
520ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    void *ptr;
521ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->allocateBuffer(
522ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, def.nBufferSize, &info.mBufferID,
523ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            &ptr);
524ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
525308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    int32_t bufSize = mUseMetadataOnEncoderOutput ?
526308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                            (4 + sizeof(buffer_handle_t)) : def.nBufferSize;
527308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
528308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    info.mData = new ABuffer(ptr, bufSize);
529ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                } else if (mQuirks & requiresAllocateBufferBit) {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    err = mOMX->allocateBufferWithBackup(
531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            mNode, portIndex, mem, &info.mBufferID);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
534ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                }
535ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
536ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                if (mem != NULL) {
537ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                    info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5391065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mBuffers[portIndex].push(info);
5411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            }
5421065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> notify = mNotify->dup();
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("what", ACodec::kWhatBuffersAllocated);
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("portIndex", portIndex);
553eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
554eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    sp<PortDescription> desc = new PortDescription;
555eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
557eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        const BufferInfo &info = mBuffers[portIndex][i];
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
559eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        desc->addBuffer(info.mBufferID, info.mData);
560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
562eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    notify->setObject("portDesc", desc);
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->post();
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
568054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarstatus_t ACodec::configureOutputBuffersFromNativeWindow(
569054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *bufferCount, OMX_U32 *bufferSize,
570054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        OMX_U32 *minUndequeuedBuffers) {
571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = kPortIndexOutput;
574f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
575f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
576f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
577f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
578f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
579f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_buffers_geometry(
583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameWidth,
585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.nFrameHeight,
586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.format.video.eColorFormat);
587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
58929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_buffers_geometry failed: %s (%d)",
590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                strerror(-err), -err);
591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Set up the native window.
5953c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    OMX_U32 usage = 0;
5963c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
5973c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    if (err != 0) {
5985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("querying usage flags from OMX IL component failed: %d", err);
5993c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        // XXX: Currently this error is logged, but not fatal.
6003c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis        usage = 0;
6013c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis    }
6023c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis
603bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (mFlags & kFlagIsSecure) {
604bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        usage |= GRALLOC_USAGE_PROTECTED;
605bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
606bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
607bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // Make sure to check whether either Stagefright or the video decoder
608bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // requested protected buffers.
609bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (usage & GRALLOC_USAGE_PROTECTED) {
610bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Verify that the ANativeWindow sends images directly to
611bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // SurfaceFlinger.
612bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        int queuesToNativeWindow = 0;
613bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->query(
614bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
615bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                &queuesToNativeWindow);
616bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != 0) {
617bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error authenticating native window: %d", err);
618bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
619bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
620bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (queuesToNativeWindow != 1) {
621bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("native window could not be authenticated");
622bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return PERMISSION_DENIED;
623bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
624bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
625bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = native_window_set_usage(
627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNativeWindow.get(),
6283c14b9745c4afc88cec247d9dd0b003e087cbb52Jamie Gennis            usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != 0) {
63129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
635054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    *minUndequeuedBuffers = 0;
636258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    err = mNativeWindow->query(
637258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis            mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
638054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            (int *)minUndequeuedBuffers);
639258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
640258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    if (err != 0) {
64129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
642258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis                strerror(-err), -err);
643258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis        return err;
644258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis    }
645258d4e3aef7984574b0972a66871afc8a13d8e4eJamie Gennis
646e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // FIXME: assume that surface is controlled by app (native window
647e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // returns the number for the case when surface is not controlled by app)
648e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    (*minUndequeuedBuffers)++;
649e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
650e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar
651e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // Use conservative allocation while also trying to reduce starvation
652e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //
653e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
654e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    minimum needed for the consumer to be able to work
655e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    // 2. try to allocate two (2) additional buffers to reduce starvation from
656e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    //    the consumer
657e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    for (OMX_U32 extraBuffers = 2; /* 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
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mIsEncoder = encoder;
1062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setComponentRole(encoder /* isEncoder */, mime);
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitRate = 0;
10702f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    // FLAC encoder doesn't need a bitrate, other encoders do
10712f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
10722f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            && !msg->findInt32("bitrate", &bitRate)) {
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1076d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    int32_t storeMeta;
1077d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (encoder
1078d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && msg->findInt32("store-metadata-in-buffers", &storeMeta)
1079d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && storeMeta != 0) {
1080d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
1081d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1082d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        if (err != OK) {
1083308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
1084308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                    mComponentName.c_str(), err);
1085d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1086308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang              return err;
1087308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang          }
1088308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang      }
1089d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
1090308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t prependSPSPPS = 0;
10913a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    if (encoder
10923a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
10933a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            && prependSPSPPS != 0) {
10943a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        OMX_INDEXTYPE index;
10953a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        err = mOMX->getExtensionIndex(
10963a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                mNode,
10973a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                "OMX.google.android.index.prependSPSPPSToIDRFrames",
10983a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                &index);
10993a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11003a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err == OK) {
11013a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            PrependSPSPPSToIDRFramesParams params;
11023a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            InitOMXParams(&params);
11033a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            params.bEnable = OMX_TRUE;
11043a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11053a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            err = mOMX->setParameter(
11063a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                    mNode, index, &params, sizeof(params));
11073a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11083a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11093a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        if (err != OK) {
11103a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            ALOGE("Encoder could not be configured to emit SPS/PPS before "
11113a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber                  "IDR frames. (err %d)", err);
11123a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
11133a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber            return err;
11143a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber        }
11153a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber    }
11163a0ef0dc71f3776d115f30d87f1d8867daefea88Andreas Huber
1117308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // Only enable metadata mode on encoder output if encoder can prepend
1118308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // sps/pps to idr frames, since in metadata mode the bitstream is in an
1119308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    // opaque handle, to which we don't have access.
1120308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    int32_t video = !strncasecmp(mime, "video/", 6);
1121308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (encoder && video) {
1122308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
1123308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
1124308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            && storeMeta != 0);
1125308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1126308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable);
1127308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1128308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        if (err != OK) {
1129308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
1130308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                mComponentName.c_str(), err);
1131308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = 0;
1132308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        } else {
1133308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            mUseMetadataOnEncoderOutput = enable;
1134308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang        }
1135a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
1136a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (!msg->findInt64(
1137a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    "repeat-previous-frame-after",
1138a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                    &mRepeatFrameDelayUs)) {
1139a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            mRepeatFrameDelayUs = -1ll;
1140a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
114194ee4b708acfa941581160b267afb79192b1d816Chong Zhang
114294ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
11432c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mMaxPtsGapUs = -1ll;
11442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
11452c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
11462c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (!msg->findInt64("time-lapse", &mTimePerCaptureUs)) {
11472c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            mTimePerCaptureUs = -1ll;
114894ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
114972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
115072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!msg->findInt32(
115172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    "create-input-buffers-suspended",
115272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    (int32_t*)&mCreateInputBuffersSuspended)) {
115372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mCreateInputBuffersSuspended = false;
115472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
1155308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    }
1156308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang
1157054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // Always try to enable dynamic output buffers on native surface
1158054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    sp<RefBase> obj;
1159054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
1160054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            obj != NULL;
1161054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mStoreMetaDataInOutputBuffers = false;
116275832930a28fd70f6fc683ed966477ceea810668Robert Shih    mIsConfiguredForAdaptivePlayback = false;
1163054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (!encoder && video && haveNativeWindow) {
1164054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
1165054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (err != OK) {
1166054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
1167054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                  mComponentName.c_str(), err);
1168fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1169fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // if adaptive playback has been requested, try JB fallback
1170fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
1171fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // LARGE MEMORY REQUIREMENT
1172fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1173fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // we will not do adaptive playback on software accessed
1174fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // surfaces as they never had to respond to changes in the
1175fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // crop window, and we don't trust that they will be able to.
1176fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int usageBits = 0;
1177fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            bool canDoAdaptivePlayback;
1178fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1179fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<NativeWindowWrapper> windowWrapper(
1180fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    static_cast<NativeWindowWrapper *>(obj.get()));
1181fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
1182fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1183fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (nativeWindow->query(
1184fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    nativeWindow.get(),
1185fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    NATIVE_WINDOW_CONSUMER_USAGE_BITS,
1186fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    &usageBits) != OK) {
1187fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback = false;
1188fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            } else {
1189fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                canDoAdaptivePlayback =
1190fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                    (usageBits &
1191fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                            (GRALLOC_USAGE_SW_READ_MASK |
1192fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                             GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
1193fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1194fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1195fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            int32_t maxWidth = 0, maxHeight = 0;
1196fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            if (canDoAdaptivePlayback &&
1197fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-width", &maxWidth) &&
1198fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                msg->findInt32("max-height", &maxHeight)) {
119984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
1200fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                      mComponentName.c_str(), maxWidth, maxHeight);
1201fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar
1202fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                err = mOMX->prepareForAdaptivePlayback(
1203fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
1204fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                ALOGW_IF(err != OK,
1205fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        "[%s] prepareForAdaptivePlayback failed w/ err %d",
1206fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar                        mComponentName.c_str(), err);
120775832930a28fd70f6fc683ed966477ceea810668Robert Shih                mIsConfiguredForAdaptivePlayback = (err == OK);
1208fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            }
1209fce0d1883cdbcb7d501625fb43844043cd28a267Lajos Molnar            // allow failure
1210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            err = OK;
1211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        } else {
1212054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
1213054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            mStoreMetaDataInOutputBuffers = true;
121475832930a28fd70f6fc683ed966477ceea810668Robert Shih            mIsConfiguredForAdaptivePlayback = true;
1215054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
12160167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber
12170167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        int32_t push;
12180167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
12190167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && push != 0) {
12200167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber            mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
12210167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        }
1222054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
1223054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
1224308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    if (video) {
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (encoder) {
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupVideoEncoder(mime, msg);
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t width, height;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("width", &width)
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || !msg->findInt32("height", &height)) {
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = INVALID_OPERATION;
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                err = setupVideoDecoder(mime, width, height);
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
123642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
123742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        int32_t numChannels, sampleRate;
123842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        if (!msg->findInt32("channel-count", &numChannels)
123942392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
124042392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // Since we did not always check for these, leave them optional
124142392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            // and have the decoder figure it all out.
124242392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = OK;
124342392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        } else {
124442392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber            err = setupRawAudioFormat(
124542392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    encoder ? kPortIndexInput : kPortIndexOutput,
124642392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    sampleRate,
124742392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber                    numChannels);
124842392e49e167c6a0c573e55e1c1b4c7fa0ceb213Andreas Huber        }
1249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t numChannels, sampleRate;
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1255aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            int32_t isADTS, aacProfile;
1256ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            if (!msg->findInt32("is-adts", &isADTS)) {
1257ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                isADTS = 0;
1258ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
1259aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            if (!msg->findInt32("aac-profile", &aacProfile)) {
1260aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke                aacProfile = OMX_AUDIO_AACObjectNull;
1261aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke            }
1262ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            err = setupAACCodec(
12644471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    encoder, numChannels, sampleRate, bitRate, aacProfile,
12654471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber                    isADTS != 0);
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1267729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
1269729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
1271729de186450f78c099637e1fce743fe531862c52Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
1272729de186450f78c099637e1fce743fe531862c52Andreas Huber            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
1273729de186450f78c099637e1fce743fe531862c52Andreas Huber        // These are PCM-like formats with a fixed sample rate but
1274729de186450f78c099637e1fce743fe531862c52Andreas Huber        // a variable number of channels.
1275729de186450f78c099637e1fce743fe531862c52Andreas Huber
1276729de186450f78c099637e1fce743fe531862c52Andreas Huber        int32_t numChannels;
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("channel-count", &numChannels)) {
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = INVALID_OPERATION;
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupG711Codec(encoder, numChannels);
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12822f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
12832f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        int32_t numChannels, sampleRate, compressionLevel = -1;
12842f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (encoder &&
12852f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                (!msg->findInt32("channel-count", &numChannels)
12862f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                        || !msg->findInt32("sample-rate", &sampleRate))) {
12872f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("missing channel count or sample rate for FLAC encoder");
12882f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            err = INVALID_OPERATION;
12892f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        } else {
12902f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            if (encoder) {
1291516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                if (!msg->findInt32(
1292516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                            "flac-compression-level", &compressionLevel)) {
12932f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 5;// default FLAC compression level
12942f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel < 0) {
1295516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1296516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 0",
1297516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
12982f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 0;
12992f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                } else if (compressionLevel > 8) {
1300516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    ALOGW("compression level %d outside [0..8] range, "
1301516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          "using 8",
1302516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                          compressionLevel);
13032f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                    compressionLevel = 8;
13042f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi                }
13052f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            }
1306516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber            err = setupFlacCodec(
1307516dacfb02d0b0eafe21114330c98ce0e7d90da9Andreas Huber                    encoder, numChannels, sampleRate, compressionLevel);
13082f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
1309ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
1310ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        int32_t numChannels, sampleRate;
1311ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        if (encoder
1312ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("channel-count", &numChannels)
1313ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber                || !msg->findInt32("sample-rate", &sampleRate)) {
1314ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = INVALID_OPERATION;
1315ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        } else {
1316ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber            err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
1317ecdd39c5af016e2fa57cbfd837aa670b706dabd3Andreas Huber        }
131897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
131997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t numChannels;
132097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        int32_t sampleRate;
132197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        if (!msg->findInt32("channel-count", &numChannels)
132297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                || !msg->findInt32("sample-rate", &sampleRate)) {
132397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = INVALID_OPERATION;
132497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        } else {
132597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            err = setupAC3Codec(encoder, numChannels, sampleRate);
132697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        }
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1328729de186450f78c099637e1fce743fe531862c52Andreas Huber
13294471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    if (err != OK) {
13304471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber        return err;
13314471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber    }
13324471e47ece77be5b4159cc9cbbcef4d43900d36fAndreas Huber
13338b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
13348b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderDelay = 0;
13358b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13369806555d3930be43e11106281dee354820ac1c88Andreas Huber
13378b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
13388b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen        mEncoderPadding = 0;
13398b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen    }
13408b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen
13419806555d3930be43e11106281dee354820ac1c88Andreas Huber    if (msg->findInt32("channel-mask", &mChannelMask)) {
13429806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = true;
13439806555d3930be43e11106281dee354820ac1c88Andreas Huber    } else {
13449806555d3930be43e11106281dee354820ac1c88Andreas Huber        mChannelMaskPresent = false;
13459806555d3930be43e11106281dee354820ac1c88Andreas Huber    }
13469806555d3930be43e11106281dee354820ac1c88Andreas Huber
1347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t maxInputSize;
1348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (msg->findInt32("max-input-size", &maxInputSize)) {
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
1350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = setMinBufferSize(kPortIndexInput, 8192);  // XXX
1352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1355f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1356f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1357f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
1358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
1360f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
1361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (def.nBufferSize >= size) {
1370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return OK;
1371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nBufferSize = size;
1374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
1376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->getParameter(
1383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1389f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(def.nBufferSize >= size);
1390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::selectAudioPortFormat(
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_AUDIO_PARAM_PORTFORMATTYPE format;
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&format);
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    format.nPortIndex = portIndex;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (OMX_U32 index = 0;; ++index) {
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        format.nIndex = index;
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioPortFormat,
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &format, sizeof(format));
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (format.eEncoding == desiredFormat) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAACCodec(
1421aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        bool encoder, int32_t numChannels, int32_t sampleRate,
1422aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        int32_t bitRate, int32_t aacProfile, bool isADTS) {
1423ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (encoder && isADTS) {
1424ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return -EINVAL;
1425ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1426ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setupRawAudioFormat(
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sampleRate,
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            numChannels);
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (encoder) {
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_PARAM_PORTDEFINITIONTYPE def;
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&def);
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.nPortIndex = kPortIndexOutput;
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.bFlagErrorConcealment = OMX_TRUE;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_AUDIO_PARAM_AACPROFILETYPE profile;
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        InitOMXParams(&profile);
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nPortIndex = kPortIndexOutput;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->getParameter(
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nChannels = numChannels;
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eChannelMode =
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (numChannels == 1)
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nSampleRate = sampleRate;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nBitRate = bitRate;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAudioBandWidth = 0;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nFrameLength = 0;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACtools = OMX_AUDIO_AACToolAll;
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.nAACERtools = OMX_AUDIO_AACERNone;
1487aeb8fd460ed87d032b3fb8bb61e21eb542ce0f5bDave Burke        profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = mOMX->setParameter(
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
1501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&profile);
1502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nPortIndex = kPortIndexInput;
1503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
1505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
1506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nChannels = numChannels;
1512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    profile.nSampleRate = sampleRate;
1513ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1514ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    profile.eAACStreamFormat =
1515ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        isADTS
1516ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            ? OMX_AUDIO_AACStreamFormatMP4ADTS
1517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            : OMX_AUDIO_AACStreamFormatMP4FF;
1518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
1520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1522f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
152397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryustatus_t ACodec::setupAC3Codec(
152497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        bool encoder, int32_t numChannels, int32_t sampleRate) {
152597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    status_t err = setupRawAudioFormat(
152697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
152797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
152897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
152997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
153097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
153197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
153297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (encoder) {
153397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        ALOGW("AC3 encoding is not supported.");
153497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return INVALID_OPERATION;
153597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
153697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
153797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    OMX_AUDIO_PARAM_ANDROID_AC3TYPE def;
153897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    InitOMXParams(&def);
153997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nPortIndex = kPortIndexInput;
154097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    err = mOMX->getParameter(
154297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
154397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
154497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
154597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
154697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
154797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    if (err != OK) {
154897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu        return err;
154997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    }
155097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nChannels = numChannels;
155297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    def.nSampleRate = sampleRate;
155397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
155497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu    return mOMX->setParameter(
155597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            mNode,
155697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
155797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            &def,
155897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            sizeof(def));
155997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu}
156097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        bool isAMRWB, int32_t bps) {
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (isAMRWB) {
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 6600) {
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB0;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 8850) {
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB1;
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 12650) {
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB2;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 14250) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB3;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 15850) {
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB4;
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 18250) {
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB5;
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 19850) {
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB6;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 23050) {
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeWB7;
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 23850 bps
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeWB8;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {  // AMRNB
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (bps <= 4750) {
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB0;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5150) {
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB1;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 5900) {
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB2;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 6700) {
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB3;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7400) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB4;
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 7950) {
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB5;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else if (bps <= 10200) {
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OMX_AUDIO_AMRBandModeNB6;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        // 12200 bps
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OMX_AUDIO_AMRBandModeNB7;
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
1607729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_AMRTYPE def;
1608729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
1610729de186450f78c099637e1fce743fe531862c52Andreas Huber
1611729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err =
1612729de186450f78c099637e1fce743fe531862c52Andreas Huber        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1613729de186450f78c099637e1fce743fe531862c52Andreas Huber
1614729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1615729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1616729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1617729de186450f78c099637e1fce743fe531862c52Andreas Huber
1618729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
1623729de186450f78c099637e1fce743fe531862c52Andreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1627729de186450f78c099637e1fce743fe531862c52Andreas Huber
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupRawAudioFormat(
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder ? kPortIndexInput : kPortIndexOutput,
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            isWAMR ? 16000 : 8000 /* sampleRate */,
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            1 /* numChannels */);
1632729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1633729de186450f78c099637e1fce743fe531862c52Andreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupG711Codec(bool encoder, int32_t numChannels) {
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!encoder);  // XXX TODO
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1637729de186450f78c099637e1fce743fe531862c52Andreas Huber    return setupRawAudioFormat(
1638729de186450f78c099637e1fce743fe531862c52Andreas Huber            kPortIndexInput, 8000 /* sampleRate */, numChannels);
1639729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1640729de186450f78c099637e1fce743fe531862c52Andreas Huber
16412f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivistatus_t ACodec::setupFlacCodec(
16422f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
16432f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16442f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    if (encoder) {
16452f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        OMX_AUDIO_PARAM_FLACTYPE def;
16462f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        InitOMXParams(&def);
16472f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nPortIndex = kPortIndexOutput;
16482f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16492f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        // configure compression level
16502f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16512f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16522f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
16532f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16542f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16552f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        def.nCompressionLevel = compressionLevel;
16562f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
16572f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        if (err != OK) {
16582f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
16592f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            return err;
16602f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi        }
16612f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    }
16622f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
16632f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi    return setupRawAudioFormat(
16642f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            encoder ? kPortIndexInput : kPortIndexOutput,
16652f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            sampleRate,
16662f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi            numChannels);
16672f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi}
16682f74ef3cdc192f817ee1121f41765f0852c1d81eJean-Michel Trivi
1669729de186450f78c099637e1fce743fe531862c52Andreas Huberstatus_t ACodec::setupRawAudioFormat(
1670729de186450f78c099637e1fce743fe531862c52Andreas Huber        OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
1671729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
1672729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&def);
1673729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.nPortIndex = portIndex;
1674729de186450f78c099637e1fce743fe531862c52Andreas Huber
1675729de186450f78c099637e1fce743fe531862c52Andreas Huber    status_t err = mOMX->getParameter(
1676729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1677729de186450f78c099637e1fce743fe531862c52Andreas Huber
1678729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1679729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1680729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1681729de186450f78c099637e1fce743fe531862c52Andreas Huber
1682729de186450f78c099637e1fce743fe531862c52Andreas Huber    def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
1683729de186450f78c099637e1fce743fe531862c52Andreas Huber
1684729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->setParameter(
1685729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
1686729de186450f78c099637e1fce743fe531862c52Andreas Huber
1687729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1688729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1689729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1690729de186450f78c099637e1fce743fe531862c52Andreas Huber
1691729de186450f78c099637e1fce743fe531862c52Andreas Huber    OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
1692729de186450f78c099637e1fce743fe531862c52Andreas Huber    InitOMXParams(&pcmParams);
1693729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nPortIndex = portIndex;
1694729de186450f78c099637e1fce743fe531862c52Andreas Huber
1695729de186450f78c099637e1fce743fe531862c52Andreas Huber    err = mOMX->getParameter(
1696729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1697729de186450f78c099637e1fce743fe531862c52Andreas Huber
1698729de186450f78c099637e1fce743fe531862c52Andreas Huber    if (err != OK) {
1699729de186450f78c099637e1fce743fe531862c52Andreas Huber        return err;
1700729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1701729de186450f78c099637e1fce743fe531862c52Andreas Huber
1702729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nChannels = numChannels;
1703729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.eNumData = OMX_NumericalDataSigned;
1704729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.bInterleaved = OMX_TRUE;
1705729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nBitPerSample = 16;
1706729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.nSamplingRate = sampleRate;
1707729de186450f78c099637e1fce743fe531862c52Andreas Huber    pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
1708729de186450f78c099637e1fce743fe531862c52Andreas Huber
1709c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber    if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
1710c1d8115e8a0bdaeb2b723d395b9a85a02c90c933Andreas Huber        return OMX_ErrorNone;
1711729de186450f78c099637e1fce743fe531862c52Andreas Huber    }
1712729de186450f78c099637e1fce743fe531862c52Andreas Huber
1713729de186450f78c099637e1fce743fe531862c52Andreas Huber    return mOMX->setParameter(
1714729de186450f78c099637e1fce743fe531862c52Andreas Huber            mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
1715729de186450f78c099637e1fce743fe531862c52Andreas Huber}
1716729de186450f78c099637e1fce743fe531862c52Andreas Huber
1717f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoPortFormatType(
1718f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
1719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_VIDEO_CODINGTYPE compressionFormat,
1720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat) {
1721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = portIndex;
1724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool found = false;
1726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_U32 index = 0;
1728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (;;) {
1729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        format.nIndex = index;
1730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        status_t err = mOMX->getParameter(
1731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mNode, OMX_IndexParamVideoPortFormat,
1732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                &format, sizeof(format));
1733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (err != OK) {
1735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return err;
1736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The following assertion is violated by TI's video decoder.
1739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // CHECK_EQ(format.nIndex, index);
1740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
1742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexInput
1743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && colorFormat == format.eColorFormat) {
1744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eCompressionFormat does not seem right.
1745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1746f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1747f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (portIndex == kPortIndexOutput
1749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    && compressionFormat == format.eCompressionFormat) {
1750f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // eColorFormat does not seem right.
1751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                found = true;
1752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                break;
1753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
1754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (format.eCompressionFormat == compressionFormat
1757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && format.eColorFormat == colorFormat) {
1758f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            found = true;
1759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
1760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
1761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ++index;
1763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (!found) {
1766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return UNKNOWN_ERROR;
1767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->setParameter(
1770f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
1774f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1776f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setSupportedOutputFormat() {
1777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PARAM_PORTFORMATTYPE format;
1778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&format);
1779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nPortIndex = kPortIndexOutput;
1780f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    format.nIndex = 0;
1781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
1783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
1786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
1787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mOMX->setParameter(
1789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamVideoPortFormat,
1790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            &format, sizeof(format));
1791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic const struct VideoCodingMapEntry {
1794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    const char *mMime;
1795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    OMX_VIDEO_CODINGTYPE mVideoCodingType;
1796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} kVideoCodingMapEntry[] = {
1797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
1798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
1799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
1800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    { MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
180194705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP8, OMX_VIDEO_CodingVP8 },
180294705aff3c9eef58cbb72ec6fe5d2dcfd9481646hkuang    { MEDIA_MIMETYPE_VIDEO_VP9, OMX_VIDEO_CodingVP9 },
1803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber};
1804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic status_t GetVideoCodingTypeFromMime(
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
1807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (!strcasecmp(mime, kVideoCodingMapEntry[i].mMime)) {
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *codingType = kVideoCodingMapEntry[i].mVideoCodingType;
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    *codingType = OMX_VIDEO_CodingUnused;
1817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
1819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1821e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatic status_t GetMimeTypeForVideoCoding(
1822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        OMX_VIDEO_CODINGTYPE codingType, AString *mime) {
1823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    for (size_t i = 0;
1824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         i < sizeof(kVideoCodingMapEntry) / sizeof(kVideoCodingMapEntry[0]);
1825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber         ++i) {
1826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (codingType == kVideoCodingMapEntry[i].mVideoCodingType) {
1827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            *mime = kVideoCodingMapEntry[i].mMime;
1828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return OK;
1829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    mime->clear();
1833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return ERROR_UNSUPPORTED;
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoDecoder(
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const char *mime, int32_t width, int32_t height) {
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
1847f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
1848f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1849f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1850f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setSupportedOutputFormat();
1854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1858f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexInput, width, height, compressionFormat);
1861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1864f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = setVideoFormatOnPort(
1867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
1868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
1870f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
1871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
1872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
1873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
1874f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
1875f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("color-format", &tmp)) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_COLOR_FORMATTYPE colorFormat =
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        static_cast<OMX_COLOR_FORMATTYPE>(tmp);
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = setVideoPortFormatType(
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support color format %d",
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str(), colorFormat);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Input port configuration */
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&def);
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexInput;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t width, height, bitrate;
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("width", &width)
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("height", &height)
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("bitrate", &bitrate)) {
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t stride;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("stride", &stride)) {
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        stride = width;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nStride = stride;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t sliceHeight;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("slice-height", &sliceHeight)) {
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sliceHeight = height;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nSliceHeight = sliceHeight;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
19442c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        mTimePerFrameUs = (int64_t) (1000000.0f / frameRate);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = colorFormat;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set input port definition parameters.",
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    /* Output port configuration */
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_CODINGTYPE compressionFormat;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = setVideoPortFormatType(
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] does not support compression format %d",
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber             mComponentName.c_str(), compressionFormat);
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    def.nPortIndex = kPortIndexOutput;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->getParameter(
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameWidth = width;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nFrameHeight = height;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->xFramerate = 0;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->nBitrate = bitrate;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eCompressionFormat = compressionFormat;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    video_def->eColorFormat = OMX_COLOR_FormatUnused;
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ALOGE("[%s] failed to set output port definition parameters.",
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber              mComponentName.c_str());
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (compressionFormat) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingMPEG4:
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupMPEG4EncoderParameters(msg);
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingH263:
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupH263EncoderParameters(msg);
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case OMX_VIDEO_CodingAVC:
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            err = setupAVCEncoderParameters(msg);
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
201989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP8:
202089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        case OMX_VIDEO_CodingVP9:
202189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            err = setupVPXEncoderParameters(msg);
202289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber            break;
202389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGI("setupVideoEncoder succeeded");
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20330dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dongstatus_t ACodec::setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode) {
20340dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    OMX_VIDEO_PARAM_INTRAREFRESHTYPE params;
20350dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    InitOMXParams(&params);
20360dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.nPortIndex = kPortIndexOutput;
20370dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20380dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    params.eRefreshMode = static_cast<OMX_VIDEO_INTRAREFRESHTYPE>(mode);
20390dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20400dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshCyclic ||
20410dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20420dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20430dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-CIR-mbs", &mbs)) {
20440dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20450dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20460dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nCirMBs = mbs;
20470dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20480dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20490dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (params.eRefreshMode == OMX_VIDEO_IntraRefreshAdaptive ||
20500dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            params.eRefreshMode == OMX_VIDEO_IntraRefreshBoth) {
20510dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t mbs;
20520dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-mbs", &mbs)) {
20530dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20540dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20550dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirMBs = mbs;
20560dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20570dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        int32_t ref;
20580dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (!msg->findInt32("intra-refresh-AIR-ref", &ref)) {
20590dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return INVALID_OPERATION;
20600dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
20610dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        params.nAirRef = ref;
20620dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
20630dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20640dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = mOMX->setParameter(
20650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            mNode, OMX_IndexParamVideoIntraRefresh,
20660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            &params, sizeof(params));
20670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    return err;
20680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong}
20690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatic OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (iFramesInterval < 0) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0xFFFFFFFF;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (iFramesInterval == 0) {
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return 0;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_U32 ret = frameRate * iFramesInterval;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(ret > 1);
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return ret;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
208196076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatic OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
208296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    int32_t tmp;
208396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    if (!msg->findInt32("bitrate-mode", &tmp)) {
208496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        return OMX_Video_ControlRateVariable;
208596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    }
208696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
208796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
208896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber}
208996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
209796076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
209896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&mpeg4type);
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPortIndex = kPortIndexOutput;
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nSliceHeaderSpacing = 0;
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bSVH = OMX_FALSE;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bGov = OMX_FALSE;
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nAllowedPictureTypes =
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mpeg4type.nPFrames == 0) {
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nBFrames = 0;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nIDCVLCThreshold = 0;
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bACPred = OMX_TRUE;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nMaxPacketSize = 256;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nTimeIncRes = 1000;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.nHeaderExtension = 0;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mpeg4type.bReversibleVLC = OMX_FALSE;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
216296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
217896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
217996076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_H263TYPE h263type;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h263type);
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPortIndex = kPortIndexOutput;
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nAllowedPictureTypes =
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h263type.nPFrames == 0) {
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nBFrames = 0;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bPLUSPTYPEAllowed = OMX_FALSE;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.bForceRoundingTypeToZero = OMX_FALSE;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nPictureHeaderRepetition = 0;
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h263type.nGOBHeaderInterval = 0;
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
223896076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    err = configureBitrate(bitrate, bitrateMode);
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return setupErrorCorrectionParameters();
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t bitrate, iFrameInterval;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("bitrate", &bitrate)
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return INVALID_OPERATION;
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225496076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
225596076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    float frameRate;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findFloat("frame-rate", &frameRate)) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t tmp;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("frame-rate", &tmp)) {
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        frameRate = (float)tmp;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22650dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    status_t err = OK;
22660dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    int32_t intraRefreshMode = 0;
22670dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    if (msg->findInt32("intra-refresh-mode", &intraRefreshMode)) {
22680dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        err = setCyclicIntraMacroblockRefresh(msg, intraRefreshMode);
22690dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        if (err != OK) {
22700dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            ALOGE("Setting intra macroblock refresh mode (%d) failed: 0x%x",
22710dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong                    err, intraRefreshMode);
22720dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong            return err;
22730dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong        }
22740dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    }
22750dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_AVCTYPE h264type;
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&h264type);
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nPortIndex = kPortIndexOutput;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22800dbe5a9321b24b6883fbb2fe97cd9d525128b0b5James Dong    err = mOMX->getParameter(
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.nAllowedPictureTypes =
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t profile;
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findInt32("profile", &profile)) {
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t level;
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("level", &level)) {
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return INVALID_OPERATION;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = verifySupportForProfileAndLevel(profile, level);
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // XXX
23087c25df82dfc8bbedb58608242f0d923a4594bb14James Dong    if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
23097c25df82dfc8bbedb58608242f0d923a4594bb14James Dong        ALOGW("Use baseline profile instead of %d for AVC recording",
23107c25df82dfc8bbedb58608242f0d923a4594bb14James Dong            h264type.eProfile);
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nSliceHeaderSpacing = 0;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bUseHadamard = OMX_TRUE;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefFrames = 1;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nBFrames = 0;
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (h264type.nPFrames == 0) {
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx10ActiveMinus1 = 0;
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nRefIdx11ActiveMinus1 = 0;
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bEntropyCodingCABAC = OMX_FALSE;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bWeightedPPrediction = OMX_FALSE;
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bconstIpred = OMX_FALSE;
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirect8x8Inference = OMX_FALSE;
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.bDirectSpatialTemporal = OMX_FALSE;
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nCabacInitIdc = 0;
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (h264type.nBFrames != 0) {
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableUEP = OMX_FALSE;
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableFMO = OMX_FALSE;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableASO = OMX_FALSE;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bEnableRS = OMX_FALSE;
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bFrameMBsOnly = OMX_TRUE;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.bMBAFF = OMX_FALSE;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    err = mOMX->setParameter(
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    return configureBitrate(bitrate, bitrateMode);
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huberstatus_t ACodec::setupVPXEncoderParameters(const sp<AMessage> &msg) {
235689b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    int32_t bitrate;
235789b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    if (!msg->findInt32("bitrate", &bitrate)) {
235889b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber        return INVALID_OPERATION;
235989b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    }
236089b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
236189b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
236289b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
236389b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber    return configureBitrate(bitrate, bitrateMode);
236489b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber}
236589b31a3f670d8bec87bed50aaad9bcd8edec66b6Andreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::verifySupportForProfileAndLevel(
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t profile, int32_t level) {
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&params);
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    params.nPortIndex = kPortIndexOutput;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err = mOMX->getParameter(
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mNode,
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                OMX_IndexParamVideoProfileLevelQuerySupported,
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                &params,
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sizeof(params));
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (err != OK) {
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return err;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (profile == supportedProfile && level <= supportedLevel) {
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return OK;
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
239296076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huberstatus_t ACodec::configureBitrate(
239396076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber        int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&bitrateType);
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nPortIndex = kPortIndexOutput;
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
240696076964863ee6887f0bed9d0f11f424b48ab9b9Andreas Huber    bitrateType.eControlRate = bitrateMode;
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bitrateType.nTargetBitrate = bitrate;
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoBitrate,
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &bitrateType, sizeof(bitrateType));
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t ACodec::setupErrorCorrectionParameters() {
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    InitOMXParams(&errorCorrectionType);
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nPortIndex = kPortIndexOutput;
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mOMX->getParameter(
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return OK;  // Optional feature. Ignore this failure
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableHEC = OMX_FALSE;
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableResync = OMX_TRUE;
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.nResynchMarkerSpacing = 256;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    errorCorrectionType.bEnableRVLC = OMX_FALSE;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return mOMX->setParameter(
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNode, OMX_IndexParamVideoErrorCorrection,
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            &errorCorrectionType, sizeof(errorCorrectionType));
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2438f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::setVideoFormatOnPort(
2439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex,
2440f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
2441f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
2442f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    InitOMXParams(&def);
2443f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    def.nPortIndex = portIndex;
2444f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2445f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
2446f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2447f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mOMX->getParameter(
2448f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2449f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(err, (status_t)OK);
2451f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2452f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2453f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // XXX Need a (much) better heuristic to compute input buffer sizes.
2454f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const size_t X = 64 * 1024;
2455f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (def.nBufferSize < X) {
2456f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            def.nBufferSize = X;
2457f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2458f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
2461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameWidth = width;
2463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    video_def->nFrameHeight = height;
2464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2465f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexInput) {
2466f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eCompressionFormat = compressionFormat;
2467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        video_def->eColorFormat = OMX_COLOR_FormatUnused;
2468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    err = mOMX->setParameter(
2471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
2472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return err;
2474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2475f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2476f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::initNativeWindow() {
2477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mNativeWindow != NULL) {
2478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
2479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
2482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return OK;
2483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2485d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Hubersize_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
2486d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    size_t n = 0;
2487d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2488d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2489d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        const BufferInfo &info = mBuffers[portIndex].itemAt(i);
2490d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2491d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
2492d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            ++n;
2493d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber        }
2494d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    }
2495d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
2496d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber    return n;
2497d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber}
2498d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
24997e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubersize_t ACodec::countBuffersOwnedByNativeWindow() const {
25007e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    size_t n = 0;
25017e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25027e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
25037e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
25047e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25057e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25067e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            ++n;
25077e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        }
25087e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25097e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25107e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    return n;
25117e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25127e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
25137e7013392e302a28364df1dcee79b82ad90978b4Andreas Hubervoid ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
25147e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    if (mNativeWindow == NULL) {
25157e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        return;
25167e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25177e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2518e257e5ebefdd50f808ee3b4d1596db261c9b62ddLajos Molnar    while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
25197e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber            && dequeueBufferFromNativeWindow() != NULL) {
2520c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        // these buffers will be submitted as regular buffers; account for this
2521c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
2522c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar            --mMetaDataBuffersToSubmit;
2523c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar        }
25247e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber    }
25257e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber}
25267e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
2527f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs(
2528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
2529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
2530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
2531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus != BufferInfo::OWNED_BY_US
2533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
25343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Buffer %p on port %ld still has status %d",
2535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mComponentName.c_str(),
2536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info->mBufferID, portIndex, info->mStatus);
2537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
2538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2539f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2540f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
2542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2544f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::allYourBuffersAreBelongToUs() {
2545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return allYourBuffersAreBelongToUs(kPortIndexInput)
2546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        && allYourBuffersAreBelongToUs(kPortIndexOutput);
2547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2549f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::deferMessage(const sp<AMessage> &msg) {
2550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool wasEmptyBefore = mDeferredQueue.empty();
2551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.push_back(msg);
2552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2554f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::processDeferredMessages() {
2555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> > queue = mDeferredQueue;
2556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mDeferredQueue.clear();
2557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    List<sp<AMessage> >::iterator it = queue.begin();
2559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    while (it != queue.end()) {
2560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        onMessageReceived(*it++);
2561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
2562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2564577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnarvoid ACodec::sendFormatChange(const sp<AMessage> &reply) {
256531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    sp<AMessage> notify = mNotify->dup();
256631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->setInt32("what", kWhatOutputFormatChanged);
256731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
256831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    OMX_PARAM_PORTDEFINITIONTYPE def;
256931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    InitOMXParams(&def);
257031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    def.nPortIndex = kPortIndexOutput;
257131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
257231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ(mOMX->getParameter(
257331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)),
257431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber             (status_t)OK);
257531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
257631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    CHECK_EQ((int)def.eDir, (int)OMX_DirOutput);
257731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
257831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    switch (def.eDomain) {
257931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainVideo:
258031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
258131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video;
258231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            AString mime;
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else if (GetMimeTypeForVideoCoding(
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        videoDef->eCompressionFormat, &mime) != OK) {
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", "application/octet-stream");
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            } else {
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setString("mime", mime.c_str());
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
259331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("width", videoDef->nFrameWidth);
259431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            notify->setInt32("height", videoDef->nFrameHeight);
259531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (!mIsEncoder) {
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("stride", videoDef->nStride);
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("slice-height", videoDef->nSliceHeight);
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setInt32("color-format", videoDef->eColorFormat);
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                OMX_CONFIG_RECTTYPE rect;
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                InitOMXParams(&rect);
2603e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                rect.nPortIndex = kPortIndexOutput;
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mOMX->getConfig(
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            mNode, OMX_IndexConfigCommonOutputCrop,
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            &rect, sizeof(rect)) != OK) {
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nLeft = 0;
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nTop = 0;
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nWidth = videoDef->nFrameWidth;
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    rect.nHeight = videoDef->nFrameHeight;
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nLeft, 0);
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nTop, 0);
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nWidth, 0u);
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_GE(rect.nHeight, 0u);
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nLeft + rect.nWidth - 1, videoDef->nFrameWidth);
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                CHECK_LE(rect.nTop + rect.nHeight - 1, videoDef->nFrameHeight);
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                notify->setRect(
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        "crop",
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft,
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop,
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nLeft + rect.nWidth - 1,
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        rect.nTop + rect.nHeight - 1);
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2628e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                if (mNativeWindow != NULL) {
2629577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                    reply->setRect(
2630577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            "crop",
2631577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft,
2632577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop,
2633577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nLeft + rect.nWidth,
2634577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                            rect.nTop + rect.nHeight);
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                }
263631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            }
263731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
263831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
263931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
264031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        case OMX_PortDomainAudio:
264131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        {
264231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def.format.audio;
264331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
264497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu            switch ((int)audioDef->eEncoding) {
2645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                case OMX_AUDIO_CodingPCM:
2646e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                {
2647e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    OMX_AUDIO_PARAM_PCMMODETYPE params;
2648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    InitOMXParams(&params);
2649e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
2650e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2651e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(mOMX->getParameter(
2652e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                mNode, OMX_IndexParamAudioPcm,
2653e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                &params, sizeof(params)),
2654e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                             (status_t)OK);
2655e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
265614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_GT(params.nChannels, 0);
2657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK(params.nChannels == 1 || params.bInterleaved);
2658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    CHECK_EQ(params.nBitPerSample, 16u);
265914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
266014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.eNumData,
266114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_NumericalDataSigned);
266214f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber
266314f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                    CHECK_EQ((int)params.ePCMMode,
266414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                             (int)OMX_AUDIO_PCMModeLinear);
2665e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2666e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
2667e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("channel-count", params.nChannels);
2668e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    notify->setInt32("sample-rate", params.nSamplingRate);
2669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mEncoderDelay + mEncoderPadding) {
2670e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        size_t frameSize = params.nChannels * sizeof(int16_t);
2671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (mSkipCutBuffer != NULL) {
2672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            size_t prevbufsize = mSkipCutBuffer->size();
2673e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (prevbufsize != 0) {
267414f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                ALOGW("Replacing SkipCutBuffer holding %d "
267514f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      "bytes",
267614f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                      prevbufsize);
2677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
2678e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
267914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                        mSkipCutBuffer = new SkipCutBuffer(
268014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderDelay * frameSize,
268114f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber                                mEncoderPadding * frameSize);
2682e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
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);
2694e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
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);
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
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);
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    params.nPortIndex = kPortIndexOutput;
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
275097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                case OMX_AUDIO_CodingAndroidAC3:
275197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                {
275297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    OMX_AUDIO_PARAM_ANDROID_AC3TYPE params;
275397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    InitOMXParams(&params);
275497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    params.nPortIndex = kPortIndexOutput;
275597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
275697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    CHECK_EQ((status_t)OK, mOMX->getParameter(
275797358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            mNode,
275897358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAc3,
275997358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            &params,
276097358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                            sizeof(params)));
276197358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu
276297358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setString("mime", MEDIA_MIMETYPE_AUDIO_AC3);
276397358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("channel-count", params.nChannels);
276497358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    notify->setInt32("sample-rate", params.nSampleRate);
276597358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                    break;
276697358c3e1adaf4a744cad78891a16d12e3e9c88eChangwan Ryu                }
2767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                default:
2769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    TRESPASS();
2770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
277131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            break;
277231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        }
277331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
277431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber        default:
277531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            TRESPASS();
277631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    }
277731e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
277831e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    notify->post();
277931e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
278031e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mSentFormat = true;
278131e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber}
278231e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
27835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
2784cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    sp<AMessage> notify = mNotify->dup();
2785cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("what", ACodec::kWhatError);
2786cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->setInt32("omx-error", error);
27875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    notify->setInt32("err", internalError);
2788cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    notify->post();
2789cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber}
2790cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber
2791bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huberstatus_t ACodec::pushBlankBuffersToNativeWindow() {
2792bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    status_t err = NO_ERROR;
2793bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    ANativeWindowBuffer* anb = NULL;
2794bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int numBufs = 0;
2795bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    int minUndequeuedBufs = 0;
2796bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2797bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We need to reconnect to the ANativeWindow as a CPU client to ensure that
2798bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // no frames get dropped by SurfaceFlinger assuming that these are video
2799bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // frames.
2800bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_disconnect(mNativeWindow.get(),
2801bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_MEDIA);
2802bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2803bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2804bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2805bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2806bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2807bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2808bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_api_connect(mNativeWindow.get(),
2809bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_API_CPU);
2810bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2811bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2812bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2813bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2814bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2815bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2816bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffers_geometry(mNativeWindow.get(), 1, 1,
2817bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            HAL_PIXEL_FORMAT_RGBX_8888);
2818bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2819bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffers_geometry failed: %s (%d)",
2820bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2821bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2822bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2823bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
282487eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    err = native_window_set_scaling_mode(mNativeWindow.get(),
282587eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
282687eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin    if (err != NO_ERROR) {
282787eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
282887eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin              strerror(-err), -err);
282987eb285dca94b20dc5f0ff8e60a0d395a4ca3be9Dima Zavin        goto error;
2830bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2831bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2832bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_usage(mNativeWindow.get(),
2833bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            GRALLOC_USAGE_SW_WRITE_OFTEN);
2834bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2835bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
2836bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2837bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2838bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2839bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2840bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = mNativeWindow->query(mNativeWindow.get(),
2841bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
2842bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2843bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
2844bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                "failed: %s (%d)", strerror(-err), -err);
2845bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2846bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2847bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2848bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    numBufs = minUndequeuedBufs + 1;
2849bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    err = native_window_set_buffer_count(mNativeWindow.get(), numBufs);
2850bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2851bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
2852bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                strerror(-err), -err);
2853bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        goto error;
2854bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2855bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2856bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // We  push numBufs + 1 buffers to ensure that we've drawn into the same
2857bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // buffer twice.  This should guarantee that the buffer has been displayed
2858bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // on the screen and then been replaced, so an previous video frames are
2859bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    // guaranteed NOT to be currently displayed.
2860bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    for (int i = 0; i < numBufs + 1; i++) {
28611e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        int fenceFd = -1;
28621e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis        err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
2863bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2864bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
2865bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2866bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2867bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2868bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2869bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
2870bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2871bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Fill the buffer with the a 1x1 checkerboard pattern ;)
2872bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        uint32_t* img = NULL;
2873bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
2874bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2875bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: lock failed: %s (%d)",
2876bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2877bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2878bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2879bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2880bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        *img = 0;
2881bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2882bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = buf->unlock();
2883bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2884bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: unlock failed: %s (%d)",
2885bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2886bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2887bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2888bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2889bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = mNativeWindow->queueBuffer(mNativeWindow.get(),
28901e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                buf->getNativeBuffer(), -1);
2891bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2892bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
2893bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2894bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            goto error;
2895bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2896bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2897bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        anb = NULL;
2898bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2899bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2900bc098410be55f9d96f394b3981a0c482b83859b6Andreas Hubererror:
2901bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2902bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    if (err != NO_ERROR) {
2903bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after an error.
2904bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (anb != NULL) {
29051e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
2906bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2907bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2908bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_disconnect(mNativeWindow.get(),
2909bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2910bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        native_window_api_connect(mNativeWindow.get(),
2911bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2912bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2913bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return err;
2914bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    } else {
2915bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        // Clean up after success.
2916bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_disconnect(mNativeWindow.get(),
2917bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_CPU);
2918bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2919bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
2920bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2921bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2922bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2923bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2924bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        err = native_window_api_connect(mNativeWindow.get(),
2925bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                NATIVE_WINDOW_API_MEDIA);
2926bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        if (err != NO_ERROR) {
2927bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
2928bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber                    strerror(-err), -err);
2929bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            return err;
2930bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
2931bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2932bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        return NO_ERROR;
2933bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber    }
2934bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber}
2935bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
2936f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
2937f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2938eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberACodec::PortDescription::PortDescription() {
2939eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2940eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2941496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t ACodec::requestIDRFrame() {
2942496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    if (!mIsEncoder) {
2943496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        return ERROR_UNSUPPORTED;
2944496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    }
2945496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    OMX_CONFIG_INTRAREFRESHVOPTYPE params;
2947496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    InitOMXParams(&params);
2948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.nPortIndex = kPortIndexOutput;
2950496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    params.IntraRefreshVOP = OMX_TRUE;
2951496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2952496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return mOMX->setConfig(
2953496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mNode,
2954496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            OMX_IndexConfigVideoIntraVOPRefresh,
2955496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            &params,
2956496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            sizeof(params));
2957496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
2958496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2959eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubervoid ACodec::PortDescription::addBuffer(
2960eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber        IOMX::buffer_id id, const sp<ABuffer> &buffer) {
2961eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBufferIDs.push_back(id);
2962eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    mBuffers.push_back(buffer);
2963eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2964eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2965eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersize_t ACodec::PortDescription::countBuffers() {
2966eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.size();
2967eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2968eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2969eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas HuberIOMX::buffer_id ACodec::PortDescription::bufferIDAt(size_t index) const {
2970eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBufferIDs.itemAt(index);
2971eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2972eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2973eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Hubersp<ABuffer> ACodec::PortDescription::bufferAt(size_t index) const {
2974eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber    return mBuffers.itemAt(index);
2975eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber}
2976eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2977eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber////////////////////////////////////////////////////////////////////////////////
2978eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
2979f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::BaseState(ACodec *codec, const sp<AState> &parentState)
2980f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : AState(parentState),
2981f933441648ef6a71dee783d733aac17b9508b452Andreas Huber      mCodec(codec) {
2982f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2983f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2984ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas HuberACodec::BaseState::PortMode ACodec::BaseState::getPortMode(
2985ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
2986f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return KEEP_BUFFERS;
2987f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
2988f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2989f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
2990f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
2991f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatInputBufferFilled:
2992f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2993f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onInputBufferFilled(msg);
2994f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
2995f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
2996f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
2997f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatOutputBufferDrained:
2998f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
2999f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onOutputBufferDrained(msg);
3000f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3001f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3002f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3003f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatOMXMessage:
3004f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3005f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXMessage(msg);
3006f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3007f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
30097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
30107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
30117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            ALOGE("Message 0x%x was not handled", msg->what());
30127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalError(OMX_ErrorUndefined, INVALID_OPERATION);
30137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            return true;
30147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
30157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3016ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        case ACodec::kWhatOMXDied:
3017ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        {
3018ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            ALOGE("OMX/mediaserver died, signalling error!");
3019ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            mCodec->signalError(OMX_ErrorResourcesLost, DEAD_OBJECT);
3020ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber            break;
3021ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        }
3022ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3023f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3024f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
3025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3030f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
3031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t type;
3032f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findInt32("type", &type));
3033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::node_id nodeID;
3035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("node", &nodeID));
3036f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(nodeID, mCodec->mNode);
3037f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (type) {
3039f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EVENT:
3040f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3041f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t event, data1, data2;
3042f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("event", &event));
3043f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data1", &data1));
3044f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("data2", &data2));
3045f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
30460af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            if (event == OMX_EventCmdComplete
30470af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data1 == OMX_CommandFlush
30480af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                    && data2 == (int32_t)OMX_ALL) {
30490af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // Use of this notification is not consistent across
30500af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // implementations. We'll drop this notification and rely
30510af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // on flush-complete notifications on the individual port
30520af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                // indices instead.
30530af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
30540af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber                return true;
30550af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber            }
30560af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
3057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEvent(
3058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_EVENTTYPE>(event),
3059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data1),
3060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    static_cast<OMX_U32>(data2));
3061f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3063f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::EMPTY_BUFFER_DONE:
3064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXEmptyBufferDone(bufferID);
3069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3070f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3071f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case omx_message::FILL_BUFFER_DONE:
3072f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3073f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            IOMX::buffer_id bufferID;
3074f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("buffer", &bufferID));
3075f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3076f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int32_t rangeOffset, rangeLength, flags;
3077f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            int64_t timeUs;
3078f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *platformPrivate;
3079f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            void *dataPtr;
3080f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3081f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_offset", &rangeOffset));
3082f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("range_length", &rangeLength));
3083f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt32("flags", &flags));
3084f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findInt64("timestamp", &timeUs));
3085f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("platform_private", &platformPrivate));
3086f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(msg->findPointer("data_ptr", &dataPtr));
3087f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3088f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return onOMXFillBufferDone(
3089f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    bufferID,
3090f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (size_t)rangeOffset, (size_t)rangeLength,
3091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    (OMX_U32)flags,
3092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    timeUs,
3093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    platformPrivate,
3094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    dataPtr);
3095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3096f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
3099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3103f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEvent(
3104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
3105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (event != OMX_EventError) {
31063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
3107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             mCodec->mComponentName.c_str(), event, data1, data2);
3108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return false;
3110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
311229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
3113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3114cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber    mCodec->signalError((OMX_ERRORTYPE)data1);
3115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3119f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
31203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] onOMXEmptyBufferDone %p",
3121349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber         mCodec->mComponentName.c_str(), bufferID);
3122349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3124f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexInput, bufferID);
3125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3129d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    const sp<AMessage> &bufferMeta = info->mData->meta();
3130d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    void *mediaBuffer;
3131d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
3132d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber            && mediaBuffer != NULL) {
3133d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // We're in "store-metadata-in-buffers" mode, the underlying
3134d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // OMX component had access to data that's implicitly refcounted
3135d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // by this "mediaBuffer" object. Now that the OMX component has
3136d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // told us that it's done with the input buffer, we can decrement
3137d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        // the mediaBuffer's reference count.
313896fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
313996fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber        ALOGV("releasing mbuf %p", mediaBuffer);
314096fc6cc65ca93009a759a3a874b82a35771b9714Andreas Huber
3141d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ((MediaBuffer *)mediaBuffer)->release();
3142d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mediaBuffer = NULL;
3143d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3144d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        bufferMeta->setPointer("mediaBuffer", NULL);
3145d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3146d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3147f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexInput);
3148f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3151f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3152f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3153f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3154f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            postFillThisBuffer(info);
3155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3158f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();  // Not currently used
3161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3164f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3168f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
3169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
3174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setInt32("what", ACodec::kWhatFillThisBuffer);
3177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setPointer("buffer-id", info->mBufferID);
3178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mData->meta()->clear();
31802d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    notify->setBuffer("buffer", info->mData);
3181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
3183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    reply->setPointer("buffer-id", info->mBufferID);
3184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->setMessage("reply", reply);
3186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    notify->post();
3188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
3190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3192f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
3193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
31962d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    sp<ABuffer> buffer;
3197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t err = OK;
31985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool eos = false;
3199a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar    PortMode mode = getPortMode(kPortIndexInput);
32005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
32012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    if (!msg->findBuffer("buffer", &buffer)) {
3202a73c954d947748a3b6f630cf2c160fe55ec596e3Lajos Molnar        /* these are unfilled buffers returned by client */
3203f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK(msg->findInt32("err", &err));
3204f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        if (err == OK) {
32067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            /* buffers with no errors are returned on MediaCodec.flush */
32077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            mode = KEEP_BUFFERS;
32087fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        } else {
32097fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            ALOGV("[%s] saw error %d instead of an input buffer",
32107fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                 mCodec->mComponentName.c_str(), err);
32117fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar            eos = true;
32127fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar        }
32133831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber
32142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber        buffer.clear();
3215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t tmp;
32185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
32195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        eos = true;
32205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = ERROR_END_OF_STREAM;
32215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
32225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
3224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
3225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3226f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3227f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3228f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (eos) {
3232dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (!mCodec->mPortEOS[kPortIndexInput]) {
3233dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
3234dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                    mCodec->mInputEOSResult = err;
3235dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3236f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3237f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3238f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3239f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3240f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3241f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
32425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
3243f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int64_t timeUs;
3244f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3245f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3246f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
3247f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3248f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                int32_t isCSD;
3249f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
3250f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    flags |= OMX_BUFFERFLAG_CODECCONFIG;
3251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
32535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (eos) {
32545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    flags |= OMX_BUFFERFLAG_EOS;
32555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
32565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (buffer != info->mData) {
3258d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
3259d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(),
3260d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         bufferID,
3261d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         buffer.get(), info->mData.get());
3262f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3263f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    CHECK_LE(buffer->size(), info->mData->capacity());
3264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    memcpy(info->mData->data(), buffer->data(), buffer->size());
3265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3267078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
32683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
3269078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID);
32705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (flags & OMX_BUFFERFLAG_EOS) {
32715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] calling emptyBuffer %p w/ EOS",
32725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str(), bufferID);
3273078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                } else {
3274d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3275d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                    ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
3276d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3277d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#else
32783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
3279078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                         mCodec->mComponentName.c_str(), bufferID, timeUs);
3280d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3281078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber                }
3282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3283d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3284d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                ACodec::BufferStats stats;
3285d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
3286d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats.mFillBufferDoneTimeUs = -1ll;
3287d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                mCodec->mBufferStats.add(timeUs, stats);
3288d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3289d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3290054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                if (mCodec->mStoreMetaDataInOutputBuffers) {
3291054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    // try to submit an output buffer for each input buffer
3292054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    PortMode outputMode = getPortMode(kPortIndexOutput);
3293054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3294054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
3295054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            mCodec->mMetaDataBuffersToSubmit,
3296054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                            (outputMode == FREE_BUFFERS ? "FREE" :
3297054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                             outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
3298054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    if (outputMode == RESUBMIT_BUFFERS) {
3299054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                        CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
3300054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                                (status_t)OK);
3301054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                    }
3302054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                }
3303054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3304f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            buffer->size(),
3309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            flags,
3310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            timeUs),
3311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (!eos) {
33165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    getMoreInputDataIfPossible();
33175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else {
33185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("[%s] Signalled EOS on the input port",
33195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         mCodec->mComponentName.c_str());
33205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
33215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mPortEOS[kPortIndexInput] = true;
33225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->mInputEOSResult = err;
33235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
3324f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (!mCodec->mPortEOS[kPortIndexInput]) {
3325dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                if (err != ERROR_END_OF_STREAM) {
33263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port "
3327dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         "due to error %d",
3328dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str(), err);
3329dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                } else {
33303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] Signalling EOS on the input port",
3331dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                         mCodec->mComponentName.c_str());
3332dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                }
3333f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
33343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] calling emptyBuffer %p signalling EOS",
3335349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                     mCodec->mComponentName.c_str(), bufferID);
3336349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3337f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->emptyBuffer(
3338f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
3339f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            bufferID,
3340f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3341f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0,
3342f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_BUFFERFLAG_EOS,
3343f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            0),
3344f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
3345f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3346f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3347f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3348f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexInput] = true;
3349dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                mCodec->mInputEOSResult = err;
3350f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3351f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3352f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3353625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih
3354625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih        default:
3355625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3356625b93f1971039a547b239f87a2dc8a8d5716589Robert Shih            break;
3357f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3358f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3359f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3360f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::getMoreInputDataIfPossible() {
3361f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mPortEOS[kPortIndexInput]) {
3362f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3363f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3364f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3365f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *eligible = NULL;
3366f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3367f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
3368f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
3369f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#if 0
3371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
3372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // There's already a "read" pending.
3373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return;
3374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif
3376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (info->mStatus == BufferInfo::OWNED_BY_US) {
3378f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            eligible = info;
3379f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3380f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3381f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3382f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (eligible == NULL) {
3383f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return;
3384f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3385f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3386f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(eligible);
3387f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3388f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3389f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::BaseState::onOMXFillBufferDone(
3390f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        IOMX::buffer_id bufferID,
3391f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        size_t rangeOffset, size_t rangeLength,
3392f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 flags,
3393f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        int64_t timeUs,
3394ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* platformPrivate */,
3395ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        void * /* dataPtr */) {
33965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
33975778822d86b0337407514b9372562b86edfa91cdAndreas Huber         mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
3398349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3399f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3400d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3401d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#if TRACK_BUFFER_TIMING
3402d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    index = mCodec->mBufferStats.indexOfKey(timeUs);
3403d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    if (index >= 0) {
3404d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ACodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
3405d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
3406d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3407d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        ALOGI("frame PTS %lld: %lld",
3408d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                timeUs,
3409d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber                stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
3410d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3411d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        mCodec->mBufferStats.removeItemsAt(index);
3412d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber        stats = NULL;
3413d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    }
3414d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#endif
3415d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber
3416f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3417f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3418f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3419f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
3420f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3421054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    info->mDequeuedAt = ++mCodec->mDequeueCounter;
3422f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    info->mStatus = BufferInfo::OWNED_BY_US;
3423f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3424f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3425f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3426f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3427f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3428f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3429f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3430f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3431f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
34325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
34335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] calling fillBuffer %p",
34345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                     mCodec->mComponentName.c_str(), info->mBufferID);
3435349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
34365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK_EQ(mCodec->mOMX->fillBuffer(
34375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mCodec->mNode, info->mBufferID),
34385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                         (status_t)OK);
3439f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
34415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
34425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
344331e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
3444577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            sp<AMessage> reply =
3445577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                new AMessage(kWhatOutputBufferDrained, mCodec->id());
3446577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
34474bdda35319d5f46efea2089b865c8a64816389cdMarco Nelissen            if (!mCodec->mSentFormat && rangeLength > 0) {
3448577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->sendFormatChange(reply);
34495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
3450f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3451308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            if (mCodec->mUseMetadataOnEncoderOutput) {
3452308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                native_handle_t* handle =
3453308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                        *(native_handle_t**)(info->mData->data() + 4);
3454308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setPointer("handle", handle);
3455308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeOffset", rangeOffset);
3456308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->meta()->setInt32("rangeLength", rangeLength);
3457308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            } else {
3458308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang                info->mData->setRange(rangeOffset, rangeLength);
3459308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang            }
3460496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber#if 0
346121ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen            if (mCodec->mNativeWindow == NULL) {
3462496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                if (IsIDR(info->mData)) {
3463496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                    ALOGI("IDR frame");
3464496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                }
34655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
346621ad778dcfcddb8f8fd9dc3fe4992fbef246c511Marco Nelissen#endif
3467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34688b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            if (mCodec->mSkipCutBuffer != NULL) {
34698b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen                mCodec->mSkipCutBuffer->submit(info->mData);
34708b71241ce7353731ab75322c46e090ee35014a33Marco Nelissen            }
34715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mData->meta()->setInt64("timeUs", timeUs);
3472f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
34745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
34755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setPointer("buffer-id", info->mBufferID);
34762d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber            notify->setBuffer("buffer", info->mData);
34775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setInt32("flags", flags);
3478f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            reply->setPointer("buffer-id", info->mBufferID);
3480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->setMessage("reply", reply);
3482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
34835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            notify->post();
34845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
3486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (flags & OMX_BUFFERFLAG_EOS) {
34885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
34895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                sp<AMessage> notify = mCodec->mNotify->dup();
3491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->setInt32("what", ACodec::kWhatEOS);
3492dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber                notify->setInt32("err", mCodec->mInputEOSResult);
3493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                notify->post();
3494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mPortEOS[kPortIndexOutput] = true;
3496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3497f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3502f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
3511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3513f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
3514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    IOMX::buffer_id bufferID;
3515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
3516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    ssize_t index;
3518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info =
3519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
3520f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
3521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3522577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    android_native_rect_t crop;
3523577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    if (msg->findRect("crop",
3524577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar            &crop.left, &crop.top, &crop.right, &crop.bottom)) {
3525577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar        CHECK_EQ(0, native_window_set_crop(
3526577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar                mCodec->mNativeWindow.get(), &crop));
3527577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar    }
3528577db6d42b8d83b3578c7e56b1391bdaca9cb705Lajos Molnar
3529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    int32_t render;
3530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mCodec->mNativeWindow != NULL
35316aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen            && msg->findInt32("render", &render) && render != 0
353279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou            && info->mData != NULL && info->mData->size() != 0) {
3533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        // The client wants this buffer to be rendered.
3534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t err;
35365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if ((err = mCodec->mNativeWindow->queueBuffer(
3537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNativeWindow.get(),
35381e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis                    info->mGraphicBuffer.get(), -1)) == OK) {
3539cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
3540cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        } else {
35415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalError(OMX_ErrorUndefined, err);
3542cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber            info->mStatus = BufferInfo::OWNED_BY_US;
3543cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        }
3544f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    } else {
3545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_US;
3546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    PortMode mode = getPortMode(kPortIndexOutput);
3549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (mode) {
3551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case KEEP_BUFFERS:
3552f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
3554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // We cannot resubmit the buffer we just rendered, dequeue
3557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                // the spare instead.
3558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                info = mCodec->dequeueBufferFromNativeWindow();
3560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3562f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3563f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3564f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case RESUBMIT_BUFFERS:
3565f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3566f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (!mCodec->mPortEOS[kPortIndexOutput]) {
3567f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
3568f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // We cannot resubmit the buffer we just rendered, dequeue
3569f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    // the spare instead.
3570f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3571f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    info = mCodec->dequeueBufferFromNativeWindow();
3572f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                }
3573f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3574c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                if (info != NULL) {
35753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("[%s] calling fillBuffer %p",
3576c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                         mCodec->mComponentName.c_str(), info->mBufferID);
3577349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
3578c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
3579c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                             (status_t)OK);
3580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3581c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                    info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
3582c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber                }
3583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
3584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3585f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3586f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3587f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)mode, (int)FREE_BUFFERS);
3590f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3591f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((status_t)OK,
3592f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->freeBuffer(kPortIndexOutput, index));
3593f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
3599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3600f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::UninitializedState::UninitializedState(ACodec *codec)
3601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
3602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::UninitializedState::stateEntered() {
3605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("Now uninitialized");
3606ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3607ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (mDeathNotifier != NULL) {
3608ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mCodec->mOMX->asBinder()->unlinkToDeath(mDeathNotifier);
3609ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3610ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3611ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3612ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNativeWindow.clear();
3613ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mNode = NULL;
3614ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mOMX.clear();
3615ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mQuirks = 0;
3616ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mFlags = 0;
3617308bcaa44e578279e61be32b572fdb0b11b1e4c7Chong Zhang    mCodec->mUseMetadataOnEncoderOutput = 0;
3618ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mCodec->mComponentName.clear();
3619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3621f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
3622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
3623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
3625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatSetup:
3626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            onSetup(msg);
3628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
3631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
36335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case ACodec::kWhatAllocateComponent:
36345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
36355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            onAllocateComponent(msg);
36365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            handled = true;
36375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
36385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
36395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatShutdown:
3641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3642c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3643c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3644c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3645c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(!keepComponentAllocated);
3646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3649f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3652c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case ACodec::kWhatFlush:
3656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
3657f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3658f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            notify->post();
3660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
3662c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber            break;
3663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
3664f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3665f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
3666f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
3667f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3668f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3669f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
3670f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
3671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3672f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::UninitializedState::onSetup(
3673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
3674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (onAllocateComponent(msg)
3675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            && mCodec->mLoadedState->onConfigureComponent(msg)) {
3676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mLoadedState->onStart();
3677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
36785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
36795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3680c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
36815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onAllocateComponent");
36825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    CHECK(mCodec->mNode == NULL);
36845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3685f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    OMXClient client;
3686f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(client.connect(), (status_t)OK);
3687f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3688f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<IOMX> omx = client.interface();
3689f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3690ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    sp<AMessage> notify = new AMessage(kWhatOMXDied, mCodec->id());
3691ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3692ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    mDeathNotifier = new DeathNotifier(notify);
3693ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    if (omx->asBinder()->linkToDeath(mDeathNotifier) != OK) {
3694ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // This was a local binder, if it dies so do we, we won't care
3695ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        // about any notifications in the afterlife.
3696ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber        mDeathNotifier.clear();
3697ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    }
3698ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber
3699e671207115fac3914134c61b336d5fa0242c68caAndreas Huber    Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
37005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AString mime;
3702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString componentName;
3704d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber    uint32_t quirks = 0;
37055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (msg->findString("componentName", &componentName)) {
3706e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        ssize_t index = matchingCodecs.add();
3707e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
3708e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        entry->mName = String8(componentName.c_str());
3709afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber
3710e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        if (!OMXCodec::findCodecQuirks(
3711e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                    componentName.c_str(), &entry->mQuirks)) {
3712e671207115fac3914134c61b336d5fa0242c68caAndreas Huber            entry->mQuirks = 0;
3713afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber        }
37145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
37155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(msg->findString("mime", &mime));
37165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t encoder;
37185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!msg->findInt32("encoder", &encoder)) {
37195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            encoder = false;
37205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
37215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        OMXCodec::findMatchingCodecs(
37235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mime.c_str(),
37245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                encoder, // createEncoder
37255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                NULL,  // matchComponentName
37265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                0,     // flags
3727e671207115fac3914134c61b336d5fa0242c68caAndreas Huber                &matchingCodecs);
37285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
37291065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37301065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    sp<CodecObserver> observer = new CodecObserver;
37311065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    IOMX::node_id node = NULL;
37321065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37331065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
37341065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            ++matchIndex) {
3735e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        componentName = matchingCodecs.itemAt(matchIndex).mName.string();
3736e671207115fac3914134c61b336d5fa0242c68caAndreas Huber        quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
3737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3738078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        pid_t tid = androidGetTid();
3739078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        int prevPriority = androidGetThreadPriority(tid);
3740078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
37411065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
3742078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber        androidSetThreadPriority(tid, prevPriority);
3743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37441065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        if (err == OK) {
37451065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber            break;
37461065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        }
37471065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
37481065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber        node = NULL;
37491065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber    }
37501065b3f17d3048948e7d522049d1980b90df3dc1Andreas Huber
3751c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    if (node == NULL) {
37525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!mime.empty()) {
37535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate a decoder for type '%s'.",
37545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                 mime.c_str());
37555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
37565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
37575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3758c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber
3759cc54fbaa69c0b69929467449d2c19192f15b5039Andreas Huber        mCodec->signalError(OMX_ErrorComponentNotFound);
3760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
3761c92fd24c10a6bf80b346d7e261325434d9c6964bAndreas Huber    }
3762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3763ac0230da14a3d223c2144b165a3a163e8519d239Andreas Huber    notify = new AMessage(kWhatOMXMessage, mCodec->id());
3764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    observer->setNotificationMessage(notify);
3765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mComponentName = componentName;
3767ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    mCodec->mFlags = 0;
3768ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3769ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    if (componentName.endsWith(".secure")) {
3770ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        mCodec->mFlags |= kFlagIsSecure;
37710167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
3772ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
3773ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3774afc16d667afa23f5aa00154ccad62f8c45cf5419Andreas Huber    mCodec->mQuirks = quirks;
3775f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mOMX = omx;
3776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->mNode = node;
3777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
37785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
37795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
37805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentAllocated);
37815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setString("componentName", mCodec->mComponentName.c_str());
37825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
37835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3784c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3785c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    mCodec->changeState(mCodec->mLoadedState);
3786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3787c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
37885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
37895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3790c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber////////////////////////////////////////////////////////////////////////////////
3791c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3792c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas HuberACodec::LoadedState::LoadedState(ACodec *codec)
3793c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    : BaseState(codec) {
3794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3796c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::stateEntered() {
3797c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
3798c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3799f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mPortEOS[kPortIndexInput] =
3800f6f38287b97ec69b169387add6458f859b770e65Andreas Huber        mCodec->mPortEOS[kPortIndexOutput] = false;
3801f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3802f6f38287b97ec69b169387add6458f859b770e65Andreas Huber    mCodec->mInputEOSResult = OK;
3803f6f38287b97ec69b169387add6458f859b770e65Andreas Huber
3804054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mDequeueCounter = 0;
3805054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    mCodec->mMetaDataBuffersToSubmit = 0;
3806a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    mCodec->mRepeatFrameDelayUs = -1ll;
380775832930a28fd70f6fc683ed966477ceea810668Robert Shih    mCodec->mIsConfiguredForAdaptivePlayback = false;
3808054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
3809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (mCodec->mShutdownInProgress) {
3810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
3811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mShutdownInProgress = false;
3813c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->mKeepComponentAllocated = false;
3814c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3815c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        onShutdown(keepComponentAllocated);
3816c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3817c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3818c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3819c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onShutdown(bool keepComponentAllocated) {
3820c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    if (!keepComponentAllocated) {
3821c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
3822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3823c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        mCodec->changeState(mCodec->mUninitializedState);
3824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3825c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3826c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> notify = mCodec->mNotify->dup();
3827c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->setInt32("what", ACodec::kWhatShutdownCompleted);
3828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    notify->post();
3829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
3832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    bool handled = false;
3833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3834c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    switch (msg->what()) {
3835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatConfigureComponent:
3836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3837c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onConfigureComponent(msg);
3838c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3839c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3840c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3841c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
38427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatCreateInputSurface:
38437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
38447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            onCreateInputSurface(msg);
38457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
38467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
38477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
38487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatStart:
3850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onStart();
3852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3854c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3855c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3856c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatShutdown:
3857c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
3859c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
3860c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
3861c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3862c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            onShutdown(keepComponentAllocated);
3863c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3866c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3867c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3868c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case ACodec::kWhatFlush:
3869c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
3870c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
3871c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
3872c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            notify->post();
3873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            handled = true;
3875c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            break;
3876c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        }
3877c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3878c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        default:
3879c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            return BaseState::onMessageReceived(msg);
3880c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    }
3881c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3882c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return handled;
3883c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
3884c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3885c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberbool ACodec::LoadedState::onConfigureComponent(
38865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg) {
38875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onConfigureComponent");
38885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(mCodec->mNode != NULL);
38905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    AString mime;
38925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findString("mime", &mime));
38935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = mCodec->configureCodec(mime.c_str(), msg);
38955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
38965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3897c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber        ALOGE("[%s] configureCodec returning error %d",
3898c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber              mCodec->mComponentName.c_str(), err);
3899c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
39005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
3901c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        return false;
39025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3903f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
3904f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    sp<RefBase> obj;
3905386d609dc513e838c7e7c4c46c604493ccd560beAndreas Huber    if (msg->findObject("native-window", &obj)
39065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
39071173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        sp<NativeWindowWrapper> nativeWindow(
39081173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                static_cast<NativeWindowWrapper *>(obj.get()));
39091173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        CHECK(nativeWindow != NULL);
39101173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        mCodec->mNativeWindow = nativeWindow->getNativeWindow();
39111ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber
39121ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber        native_window_set_scaling_mode(
39131ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                mCodec->mNativeWindow.get(),
39141ec498e67f78fb0c3ab2a1cd9a071e6356618dadAndreas Huber                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
3915f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
3916f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
3917f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
39185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
39195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
39205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->setInt32("what", ACodec::kWhatComponentConfigured);
39215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        notify->post();
39225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3923c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
3924c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return true;
39255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
39265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
39277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenvoid ACodec::LoadedState::onCreateInputSurface(
3928ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        const sp<AMessage> & /* msg */) {
39297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    ALOGV("onCreateInputSurface");
39307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> notify = mCodec->mNotify->dup();
39327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
39337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<IGraphicBufferProducer> bufferProducer;
39357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err;
39367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
39377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    err = mCodec->mOMX->createInputSurface(mCodec->mNode, kPortIndexInput,
39387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            &bufferProducer);
3939a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3940a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    if (err == OK && mCodec->mRepeatFrameDelayUs > 0ll) {
3941a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        err = mCodec->mOMX->setInternalOption(
3942a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                mCodec->mNode,
3943a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                kPortIndexInput,
3944a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY,
3945a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                &mCodec->mRepeatFrameDelayUs,
3946a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                sizeof(mCodec->mRepeatFrameDelayUs));
3947a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
3948a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        if (err != OK) {
3949a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber            ALOGE("[%s] Unable to configure option to repeat previous "
3950a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  "frames (err %d)",
3951a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  mCodec->mComponentName.c_str(),
3952a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber                  err);
3953a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber        }
3954a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber    }
3955a61285dcf1da8a2cf40c499ee3a7b9fc4d74ac58Andreas Huber
39562c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mMaxPtsGapUs > 0ll) {
395794ee4b708acfa941581160b267afb79192b1d816Chong Zhang        err = mCodec->mOMX->setInternalOption(
395894ee4b708acfa941581160b267afb79192b1d816Chong Zhang                mCodec->mNode,
395994ee4b708acfa941581160b267afb79192b1d816Chong Zhang                kPortIndexInput,
396094ee4b708acfa941581160b267afb79192b1d816Chong Zhang                IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
396194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                &mCodec->mMaxPtsGapUs,
396294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                sizeof(mCodec->mMaxPtsGapUs));
396394ee4b708acfa941581160b267afb79192b1d816Chong Zhang
396494ee4b708acfa941581160b267afb79192b1d816Chong Zhang        if (err != OK) {
396594ee4b708acfa941581160b267afb79192b1d816Chong Zhang            ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
396672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mCodec->mComponentName.c_str(),
396772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    err);
39682c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
39692c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
39702c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
39712c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    if (err == OK && mCodec->mTimePerCaptureUs > 0ll
39722c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            && mCodec->mTimePerFrameUs > 0ll) {
39732c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        int64_t timeLapse[2];
39742c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[0] = mCodec->mTimePerFrameUs;
39752c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        timeLapse[1] = mCodec->mTimePerCaptureUs;
39762c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        err = mCodec->mOMX->setInternalOption(
39772c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                mCodec->mNode,
39782c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                kPortIndexInput,
39792c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                IOMX::INTERNAL_OPTION_TIME_LAPSE,
39802c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                &timeLapse[0],
39812c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                sizeof(timeLapse));
39822c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang
39832c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        if (err != OK) {
39842c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang            ALOGE("[%s] Unable to configure time lapse (err %d)",
39852c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    mCodec->mComponentName.c_str(),
39862c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang                    err);
39872c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang        }
39882c9c8cba8562cc3a27532e4cd348912cc78d8d98Chong Zhang    }
398972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
399072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err == OK && mCodec->mCreateInputBuffersSuspended) {
399172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        bool suspend = true;
399272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = mCodec->mOMX->setInternalOption(
399372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mCodec->mNode,
399472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                kPortIndexInput,
399572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                IOMX::INTERNAL_OPTION_SUSPEND,
399672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                &suspend,
399772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sizeof(suspend));
399872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
399972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
400072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("[%s] Unable to configure option to suspend (err %d)",
400194ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  mCodec->mComponentName.c_str(),
400294ee4b708acfa941581160b267afb79192b1d816Chong Zhang                  err);
400394ee4b708acfa941581160b267afb79192b1d816Chong Zhang        }
400494ee4b708acfa941581160b267afb79192b1d816Chong Zhang    }
400594ee4b708acfa941581160b267afb79192b1d816Chong Zhang
40067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == OK) {
40077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setObject("input-surface",
40087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                new BufferProducerWrapper(bufferProducer));
40097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
40107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // Can't use mCodec->signalError() here -- MediaCodec won't forward
40117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // the error through because it's in the "configured" state.  We
40127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // send a kWhatInputSurfaceCreated with an error value instead.
40137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGE("[%s] onCreateInputSurface returning error %d",
40147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                mCodec->mComponentName.c_str(), err);
40157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        notify->setInt32("err", err);
40167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
40177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    notify->post();
40187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
40197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4020c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Hubervoid ACodec::LoadedState::onStart() {
40215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ALOGV("onStart");
40225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mCodec->mOMX->sendCommand(
40245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4025f933441648ef6a71dee783d733aac17b9508b452Andreas Huber             (status_t)OK);
4026f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4027f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->changeState(mCodec->mLoadedToIdleState);
4028f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4029f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4030f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4031f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4032f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::LoadedToIdleState::LoadedToIdleState(ACodec *codec)
4033f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4034f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4035f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4036f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::LoadedToIdleState::stateEntered() {
40373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
4038f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4039cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    status_t err;
4040cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    if ((err = allocateBuffers()) != OK) {
404129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to allocate buffers after transitioning to IDLE state "
4042cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             "(error 0x%08x)",
4043cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber             err);
4044cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
40455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodec->signalError(OMX_ErrorUndefined, err);
404691bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber
404791bfadb4aa75444c60e9949232de3c184cfe060aAndreas Huber        mCodec->changeState(mCodec->mLoadedState);
4048cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber    }
4049f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4050f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4051f933441648ef6a71dee783d733aac17b9508b452Andreas Huberstatus_t ACodec::LoadedToIdleState::allocateBuffers() {
4052f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
4053f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4054f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (err != OK) {
4055f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return err;
4056f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4057f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4058f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return mCodec->allocateBuffersOnPort(kPortIndexOutput);
4059f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4060f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4061f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4062f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
406372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4064f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4065f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4066f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4067f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4068f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4069f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
40706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
40716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
40726507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
40736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
40746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
40756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
40766463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatResume:
40776463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40786463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We'll be active soon enough.
40796463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40806463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40816463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
40826463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        case kWhatFlush:
40836463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        {
40846463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            // We haven't even started yet, so we're flushed alright...
40856463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            sp<AMessage> notify = mCodec->mNotify->dup();
40866463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->setInt32("what", ACodec::kWhatFlushCompleted);
40876463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            notify->post();
40886463e76d41430f9b03a79b221de84255f2475658Marco Nelissen            return true;
40896463e76d41430f9b03a79b221de84255f2475658Marco Nelissen        }
40906463e76d41430f9b03a79b221de84255f2475658Marco Nelissen
4091f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4092f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4093f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4094f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4095f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4096f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::LoadedToIdleState::onOMXEvent(
4097f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4098f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4099f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4100f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4101f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4102f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4103f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4104f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
4106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4107f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4108f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mIdleToExecutingState);
4109f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4110f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4111f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4112f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4115f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4116f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4117f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4118f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4119f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4120f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToExecutingState::IdleToExecutingState(ACodec *codec)
4121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4123f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4124f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToExecutingState::stateEntered() {
41253856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
4126f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4128f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
413072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatSetParameters:
4131f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4135f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4136f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4137d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatResume:
4138d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4139d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We'll be active soon enough.
4140d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4141d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4142d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4143d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        case kWhatFlush:
4144d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        {
4145d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            // We haven't even started yet, so we're flushed alright...
4146d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            sp<AMessage> notify = mCodec->mNotify->dup();
4147d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->setInt32("what", ACodec::kWhatFlushCompleted);
4148d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            notify->post();
4149d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
4150d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber            return true;
4151d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber        }
4152d477b8d071826c0768620f7ac302f31d8b12b1caAndreas Huber
41536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        case kWhatSignalEndOfInputStream:
41546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        {
41556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
41566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            return true;
41576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        }
41586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4159f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4160f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onMessageReceived(msg);
4161f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4162f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4163f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4164f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToExecutingState::onOMXEvent(
4165f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4166f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4167f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4168f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
4171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mExecutingState->resume();
4173f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingState);
4174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4175f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4176f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4177f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4178f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4179f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4180f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4181f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4182f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4183f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4185f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingState::ExecutingState(ACodec *codec)
4186349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    : BaseState(codec),
4187349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber      mActive(false) {
4188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4190f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::ExecutingState::getPortMode(
4191ccb067b1d8424ba610cbd3de83368bd55b532b5bAndreas Huber        OMX_U32 /* portIndex */) {
4192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4195054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputMetaBuffers() {
4196054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // submit as many buffers as there are input buffers with the codec
4197054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    // in case we are in port reconfiguring
4198054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
4199054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
4200054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4201054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
4202054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar            if (mCodec->submitOutputMetaDataBuffer() != OK)
4203054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                break;
4204054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        }
4205054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
42064dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
42074dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
42084dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
4209054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4210054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4211054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitRegularOutputBuffers() {
4212f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
4213f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
4214f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4215f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        if (mCodec->mNativeWindow != NULL) {
4216f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK(info->mStatus == BufferInfo::OWNED_BY_US
4217f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
4218f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4219f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
4220f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                continue;
4221f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4222f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        } else {
4223f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
4224f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4225f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
42263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] calling fillBuffer %p",
4227349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str(), info->mBufferID);
4228349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4229f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
4230f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4231f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4232f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
4233f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4234f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4235f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4236054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnarvoid ACodec::ExecutingState::submitOutputBuffers() {
4237c38fcfba95f711e5738e4c72bd5499317a2f30d9Lajos Molnar    submitRegularOutputBuffers();
4238054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    if (mCodec->mStoreMetaDataInOutputBuffers) {
4239054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar        submitOutputMetaBuffers();
4240054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar    }
4241054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar}
4242054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar
4243f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::resume() {
4244349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    if (mActive) {
42453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%s] We're already active, no need to resume.",
4246349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber             mCodec->mComponentName.c_str());
4247349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4248349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        return;
4249349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    }
4250349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4251f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    submitOutputBuffers();
4252f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4253f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    // Post the first input buffer.
4254f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
4255f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
4256f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4257f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    postFillThisBuffer(info);
4258349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4259349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber    mActive = true;
4260f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4261f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4262f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingState::stateEntered() {
42633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
4264f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4265f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mCodec->processDeferredMessages();
4266f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4267f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4268f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
4269f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4270f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4271f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4272f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4273f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4274c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            int32_t keepComponentAllocated;
4275c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->findInt32(
4276c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        "keepComponentAllocated", &keepComponentAllocated));
4277c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4278c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mShutdownInProgress = true;
4279c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->mKeepComponentAllocated = keepComponentAllocated;
4280c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
4281349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4282349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4283f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4284f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
4285f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4286f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4287f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mExecutingToIdleState);
4288f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4289f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4290f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4291f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4292f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4293f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4294f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
42957a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong            ALOGV("[%s] ExecutingState flushing now "
4296d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                 "(codec owns %d/%d input, %d/%d output).",
4297d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mComponentName.c_str(),
4298d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexInput),
4299d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexInput].size(),
4300d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
4301d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber                    mCodec->mBuffers[kPortIndexOutput].size());
4302d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4303349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mActive = false;
4304349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4305f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(mCodec->mOMX->sendCommand(
4306f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mNode, OMX_CommandFlush, OMX_ALL),
4307f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     (status_t)OK);
4308f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4309f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->changeState(mCodec->mFlushingState);
4310f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4311f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4312f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4313f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4314f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatResume:
4315f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4316f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            resume();
4317f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4318f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4319f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4320f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4321f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4322496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
4323496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
4324496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            status_t err = mCodec->requestIDRFrame();
4325496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            if (err != OK) {
4326496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber                ALOGW("Requesting an IDR frame failed.");
4327496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            }
4328496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4329496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            handled = true;
4330496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
4331496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
4332496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
4333a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
4334a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
4335a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
4336a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
4337a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4338a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = mCodec->setParameters(params);
4339a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4340a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> reply;
4341a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (msg->findMessage("reply", &reply)) {
4342a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->setInt32("err", err);
4343a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                reply->post();
4344a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            }
4345a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4346a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            handled = true;
4347a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
4348a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4349a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
43507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case ACodec::kWhatSignalEndOfInputStream:
43517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
43526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            mCodec->onSignalEndOfInputStream();
43537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            handled = true;
43547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
43557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
43567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
43574dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
43584dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        case kWhatSubmitOutputMetaDataBufferIfEOS:
43594dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        {
43604dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            if (mCodec->mPortEOS[kPortIndexInput] &&
43614dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    !mCodec->mPortEOS[kPortIndexOutput]) {
43624dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                status_t err = mCodec->submitOutputMetaDataBuffer();
43634dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                if (err == OK) {
43644dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                    mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
43654dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar                }
43664dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            }
43674dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar            return true;
43684dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar        }
43694dd0a8a3d66c2853faf2834565b3c5df4f68734dLajos Molnar
4370f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4371f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4372f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4373f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4374f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4375f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4376f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4377f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4378a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t ACodec::setParameters(const sp<AMessage> &params) {
4379a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    int32_t videoBitrate;
4380530fdbdc1b5491f3fbf172752834d1515701e142Lajos Molnar    if (params->findInt32("video-bitrate", &videoBitrate)) {
4381a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        OMX_VIDEO_CONFIG_BITRATETYPE configParams;
4382a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        InitOMXParams(&configParams);
4383a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nPortIndex = kPortIndexOutput;
4384a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        configParams.nEncodeBitrate = videoBitrate;
4385a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4386a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        status_t err = mOMX->setConfig(
4387a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                mNode,
4388a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                OMX_IndexConfigVideoBitrate,
4389a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                &configParams,
4390a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                sizeof(configParams));
4391a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4392a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        if (err != OK) {
4393a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            ALOGE("setConfig(OMX_IndexConfigVideoBitrate, %d) failed w/ err %d",
4394a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                   videoBitrate, err);
4395a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
4396a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            return err;
4397a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
4398a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    }
4399a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
440072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int64_t skipFramesBeforeUs;
440172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (params->findInt64("skip-frames-before", &skipFramesBeforeUs)) {
440272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err =
440372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOMX->setInternalOption(
440472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     mNode,
440572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     kPortIndexInput,
440672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     IOMX::INTERNAL_OPTION_START_TIME,
440772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     &skipFramesBeforeUs,
440872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                     sizeof(skipFramesBeforeUs));
440972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
441072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
441172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGE("Failed to set parameter 'skip-frames-before' (err %d)", err);
441272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
441372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
441472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
441572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4416e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    int32_t dropInputFrames;
4417e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    if (params->findInt32("drop-input-frames", &dropInputFrames)) {
4418e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber        bool suspend = dropInputFrames != 0;
4419e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4420b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err =
4421b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            mOMX->setInternalOption(
4422e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     mNode,
4423e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     kPortIndexInput,
4424e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     IOMX::INTERNAL_OPTION_SUSPEND,
4425e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber                     &suspend,
4426b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber                     sizeof(suspend));
4427b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4428b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4429b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Failed to set parameter 'drop-input-frames' (err %d)", err);
4430b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4431b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4432b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    }
4433b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4434b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    int32_t dummy;
4435b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber    if (params->findInt32("request-sync", &dummy)) {
4436b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        status_t err = requestIDRFrame();
4437b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber
4438b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        if (err != OK) {
4439b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            ALOGE("Requesting a sync frame failed w/ err %d", err);
4440b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber            return err;
4441b8689b31813f55cbc1bf8e9ca0d46a9ee113e38aAndreas Huber        }
4442e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber    }
4443e40cda70eec141fa05cbcca1de420fdb22b98be6Andreas Huber
4444a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
4445a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
4446a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
44476507d14c6d10f93d390de62b9eed267f9b544985Andy McFaddenvoid ACodec::onSignalEndOfInputStream() {
44486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    sp<AMessage> notify = mNotify->dup();
44496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
44506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
44516507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    status_t err = mOMX->signalEndOfInputStream(mNode);
44526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    if (err != OK) {
44536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        notify->setInt32("err", err);
44546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    }
44556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden    notify->post();
44566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden}
44576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
4458f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingState::onOMXEvent(
4459f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4460f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4461f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventPortSettingsChanged:
4462f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4463f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
4464f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
446531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
4466054e7347cc60ad4b9dd2e8f456406f122f9f5879Lajos Molnar                mCodec->mMetaDataBuffersToSubmit = 0;
4467f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4468f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode,
4469f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            OMX_CommandPortDisable, kPortIndexOutput),
4470f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4471f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4472349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                mCodec->freeOutputBuffersNotOwnedByComponent();
4473f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4474f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
447531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber            } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
447631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
4477f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
44783856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
4479f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                     mCodec->mComponentName.c_str(), data2);
4480f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4481f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4482f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4483f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4484f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4485f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventBufferFlag:
4486f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4487f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4488f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4489f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4490f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4491f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4492f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4493f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4494f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4495f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4496f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4497f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
4498f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        ACodec *codec)
4499f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4500f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4501f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4502f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::BaseState::PortMode ACodec::OutputPortSettingsChangedState::getPortMode(
4503f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_U32 portIndex) {
4504f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (portIndex == kPortIndexOutput) {
4505f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        return FREE_BUFFERS;
4506f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4507f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4508f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
4509f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4510f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return RESUBMIT_BUFFERS;
4511f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4512f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4513f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onMessageReceived(
4514f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4515f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4516f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4517f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4518f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4519f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4520349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case kWhatResume:
4521f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4522349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            if (msg->what() == kWhatResume) {
45233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
4524349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            }
4525349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4526f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4527f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4528f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4529f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4530f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4531f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4532f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4533f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4534f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4535f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4536f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4537f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4538f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4539f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::OutputPortSettingsChangedState::stateEntered() {
45403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now handling output port settings change",
4541f933441648ef6a71dee783d733aac17b9508b452Andreas Huber         mCodec->mComponentName.c_str());
4542f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4543f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4544f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::OutputPortSettingsChangedState::onOMXEvent(
4545f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4546f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4547f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4548f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4549f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data1 == (OMX_U32)OMX_CommandPortDisable) {
4550f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4551f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
45523856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now disabled.",
4553f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4554f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4555f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mCodec->mBuffers[kPortIndexOutput].isEmpty());
4556f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->mDealer[kPortIndexOutput].clear();
4557f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4558f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(mCodec->mOMX->sendCommand(
4559f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                            mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
4560f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                         (status_t)OK);
4561f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4562cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                status_t err;
4563cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                if ((err = mCodec->allocateBuffersOnPort(
4564cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                                kPortIndexOutput)) != OK) {
456529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Failed to allocate output port buffers after "
4566cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         "port reconfiguration (error 0x%08x)",
4567cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                         err);
4568cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber
45695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalError(OMX_ErrorUndefined, err);
4570d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4571755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // This is technically not correct, but appears to be
4572755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the only way to free the component instance.
4573755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // Controlled transitioning from excecuting->idle
4574755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // and idle->loaded seem impossible probably because
4575755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    // the output port never finishes re-enabling.
4576755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mShutdownInProgress = true;
4577755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->mKeepComponentAllocated = false;
4578755b9861197f1566f916785ba7d35cf86fd5b2d5Andreas Huber                    mCodec->changeState(mCodec->mLoadedState);
4579cb67cd1b51ff9ab221e3124cf7e546515fef3c87Andreas Huber                }
4580f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4581f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4582f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
4583f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
4584f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
458531e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber                mCodec->mSentFormat = false;
458631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
45873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("[%s] Output port now reenabled.",
4588f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                        mCodec->mComponentName.c_str());
4589f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4590349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                if (mCodec->mExecutingState->active()) {
4591349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                    mCodec->mExecutingState->submitOutputBuffers();
4592349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                }
4593349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4594f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mCodec->changeState(mCodec->mExecutingState);
4595f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4596f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                return true;
4597f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4598f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4599f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4600f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4601f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4602f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4603f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return false;
4604f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4605f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4606f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4607f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4608f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4609f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::ExecutingToIdleState::ExecutingToIdleState(ACodec *codec)
46105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : BaseState(codec),
46115778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mComponentNowIdle(false) {
4612f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4613f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4614f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
4615f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4616f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4617f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4618f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4619f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4620f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4621f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4622f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4623f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4624f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4625f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4626f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4627f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4628f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4629f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4630f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4631f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4632f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4633f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4634f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4635f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4636f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4637f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4638f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4639f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4640f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4641f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4642f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::stateEntered() {
46433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
464431e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber
46455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mComponentNowIdle = false;
464631e2508c75018145a8238925ff1a08cbde4e799aAndreas Huber    mCodec->mSentFormat = false;
4647f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4648f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4649f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::ExecutingToIdleState::onOMXEvent(
4650f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4651f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4652f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4653f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4654f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4655f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
4656f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mComponentNowIdle = true;
46585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4659f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            changeStateIfWeOwnAllBuffers();
4660f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4661f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4662f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4663f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4664349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4665349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventBufferFlag:
4666349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4667349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            // We're shutting down and don't care about this anymore.
4668349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4669349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4670349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4671f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4672f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4673f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4674f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
46750af941927ef8f35f2da5380dfd8d04b7f4ed3532Andreas Huber
4676f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
46775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
4678f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->mOMX->sendCommand(
4679f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                    mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
4680f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                 (status_t)OK);
4681f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4682f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
4683f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
4684f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
46850167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber        if ((mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown)
46860167414e261f88a96b5e4bf6cb592e6ca11e5a95Andreas Huber                && mCodec->mNativeWindow != NULL) {
4687bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // We push enough 1x1 blank buffers to ensure that one of
4688bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // them has made it to the display.  This allows the OMX
4689bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // component teardown to zero out any protected buffers
4690bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            // without the risk of scanning out one of those buffers.
4691bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber            mCodec->pushBlankBuffersToNativeWindow();
4692bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber        }
4693bc098410be55f9d96f394b3981a0c482b83859b6Andreas Huber
4694f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mIdleToLoadedState);
4695f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4696f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4697f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4698f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onInputBufferFilled(
4699f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4700f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4701f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4702f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4703f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4704f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4705f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::ExecutingToIdleState::onOutputBufferDrained(
4706f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        const sp<AMessage> &msg) {
4707f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4708f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4709f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4710f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4711f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4712f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4713f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4714f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::IdleToLoadedState::IdleToLoadedState(ACodec *codec)
4715f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4716f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4717f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4718f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
4719f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4720f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4721f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4722f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4723f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4724f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing that...
4725f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4726f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4727f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4728f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4729f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4730f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4731f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4732f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // Don't send me a flush request if you previously wanted me
4733f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // to shutdown.
4734f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            TRESPASS();
4735f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4736f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4737f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4738f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4739f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4740f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4741f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4742f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4743f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4744f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4745f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4746f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::IdleToLoadedState::stateEntered() {
47473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
4748f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4749f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4750f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::IdleToLoadedState::onOMXEvent(
4751f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
4752f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4753f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4754f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4755f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
4756f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
4757f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4758c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mCodec->changeState(mCodec->mLoadedState);
4759f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4760f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4761f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4762f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4763f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4764f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4765f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4766f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4767f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4768f933441648ef6a71dee783d733aac17b9508b452Andreas Huber////////////////////////////////////////////////////////////////////////////////
4769f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4770f933441648ef6a71dee783d733aac17b9508b452Andreas HuberACodec::FlushingState::FlushingState(ACodec *codec)
4771f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    : BaseState(codec) {
4772f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4773f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4774f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::stateEntered() {
47753856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
4776f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4777f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
4778f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4779f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4780f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
4781f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    bool handled = false;
4782f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4783f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (msg->what()) {
4784f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatShutdown:
4785f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4786f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->deferMessage(msg);
4787f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4788f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4789f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4790f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case kWhatFlush:
4791f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4792f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            // We're already doing this right now.
4793f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = true;
4794f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4795f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4796f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4797f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4798f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            handled = BaseState::onMessageReceived(msg);
4799f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            break;
4800f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4801f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4802f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return handled;
4803f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4804f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4805f933441648ef6a71dee783d733aac17b9508b452Andreas Huberbool ACodec::FlushingState::onOMXEvent(
4806f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
48077a3a2b2f9bb9421dcf83fbd47276e57917078aefJames Dong    ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
4808d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber            mCodec->mComponentName.c_str(), event, data1);
4809d3d822204249eaca4259bdf46f6f0357b96e8e21Andreas Huber
4810f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    switch (event) {
4811f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        case OMX_EventCmdComplete:
4812f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        {
4813f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
4814f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4815f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
4816f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(!mFlushComplete[data2]);
4817f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                mFlushComplete[data2] = true;
4818e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber
4819e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                if (mFlushComplete[kPortIndexInput]
4820e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                        && mFlushComplete[kPortIndexOutput]) {
4821e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                    changeStateIfWeOwnAllBuffers();
4822e5bf6409774fe73f968b7db215f535b64de66139Andreas Huber                }
4823f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            } else {
4824f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK_EQ(data2, OMX_ALL);
4825f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexInput]);
4826f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                CHECK(mFlushComplete[kPortIndexOutput]);
4827f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4828f933441648ef6a71dee783d733aac17b9508b452Andreas Huber                changeStateIfWeOwnAllBuffers();
4829f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            }
4830f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4831f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return true;
4832f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        }
4833f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4834349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        case OMX_EventPortSettingsChanged:
4835349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        {
4836349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
4837349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("type", omx_message::EVENT);
4838349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setPointer("node", mCodec->mNode);
4839349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("event", event);
4840349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data1", data1);
4841349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            msg->setInt32("data2", data2);
4842349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
48433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
4844349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber                 mCodec->mComponentName.c_str());
4845349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4846349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            mCodec->deferMessage(msg);
4847349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4848349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber            return true;
4849349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber        }
4850349d3fcb4afacf754f7b5b5186d2f258f5bf35e7Andreas Huber
4851f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        default:
4852f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            return BaseState::onOMXEvent(event, data1, data2);
4853f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4854f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4855f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    return true;
4856f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4857f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4858f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
4859f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onOutputBufferDrained(msg);
4860f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4861f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4862f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4863f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4864f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
4865f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    BaseState::onInputBufferFilled(msg);
4866f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4867f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    changeStateIfWeOwnAllBuffers();
4868f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4869f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4870f933441648ef6a71dee783d733aac17b9508b452Andreas Hubervoid ACodec::FlushingState::changeStateIfWeOwnAllBuffers() {
4871f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    if (mFlushComplete[kPortIndexInput]
4872f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mFlushComplete[kPortIndexOutput]
4873f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            && mCodec->allYourBuffersAreBelongToUs()) {
48747e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // We now own all buffers except possibly those still queued with
48757e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        // the native window for rendering. Let's get those back as well.
48767e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber        mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
48777e7013392e302a28364df1dcee79b82ad90978b4Andreas Huber
4878f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        sp<AMessage> notify = mCodec->mNotify->dup();
4879f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->setInt32("what", ACodec::kWhatFlushCompleted);
4880f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        notify->post();
4881f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4882f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->mPortEOS[kPortIndexInput] =
4883f933441648ef6a71dee783d733aac17b9508b452Andreas Huber            mCodec->mPortEOS[kPortIndexOutput] = false;
4884f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4885dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber        mCodec->mInputEOSResult = OK;
4886dc9bacd838442a524585887e6ea6696836be2edaAndreas Huber
4887f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        if (mCodec->mSkipCutBuffer != NULL) {
4888f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen            mCodec->mSkipCutBuffer->clear();
4889f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen        }
4890f3bd1972e039c6ded5154db715e5a32f1813a239Marco Nelissen
4891f933441648ef6a71dee783d733aac17b9508b452Andreas Huber        mCodec->changeState(mCodec->mExecutingState);
4892f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    }
4893f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}
4894f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
4895f933441648ef6a71dee783d733aac17b9508b452Andreas Huber}  // namespace android
4896